Files
CRBoxInputView/CRBoxInputView/Classes/CRBoxInputView.m

260 lines
7.1 KiB
Mathematica
Raw Normal View History

2019-01-03 18:03:44 +08:00
//
// CRBoxInputView.m
// CRBoxInputView
//
// Created by Chobits on 2019/1/3.
// Copyright © 2019 Chobits. All rights reserved.
//
#import "CRBoxInputView.h"
#import "Masonry.h"
#import "CRBoxInputCell.h"
2019-01-03 18:43:31 +08:00
#import "CRBoxTextView.h"
2019-01-03 18:03:44 +08:00
2019-01-03 19:13:36 +08:00
typedef NS_ENUM(NSInteger, CRBoxTextChangeType) {
CRBoxTextChangeType_NoChange,
CRBoxTextChangeType_Insert,
CRBoxTextChangeType_Delete,
};
2019-01-03 18:03:44 +08:00
@interface CRBoxInputView () <UITextViewDelegate, UICollectionViewDataSource, UICollectionViewDelegate>
{
2019-01-03 19:13:36 +08:00
NSInteger _oldLength;
2019-01-03 18:03:44 +08:00
}
2019-01-03 18:43:31 +08:00
@property (nonatomic, strong) CRBoxTextView *textView;
2019-01-03 18:03:44 +08:00
@property (nonatomic, strong) UICollectionView *mainCollectionView;
2019-01-03 19:13:36 +08:00
@property (nonatomic, strong) NSMutableArray <NSString *> *valueArr;
2019-01-03 18:03:44 +08:00
@end
@implementation CRBoxInputView
-(instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self initDefaultValue];
}
return self;
}
-(instancetype)init
{
self = [super init];
if (self) {
[self initDefaultValue];
}
return self;
}
-(void)initDefaultValue{
//
2019-01-03 19:13:36 +08:00
_oldLength = 0;
2019-01-03 19:44:13 +08:00
self.securityDelay = 0.3;
2019-01-03 18:03:44 +08:00
self.codeLength = 4;
self.ifNeedCursor = YES;
self.backgroundColor = [UIColor clearColor];
_valueArr = [NSMutableArray new];
[self beginEdit];
}
-(void)loadAndPrepareView{
if (_codeLength<=0) {
NSAssert(NO, @"请输入大于0的验证码位数");
return;
}
[self addSubview:self.mainCollectionView];
[self.mainCollectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(UIEdgeInsetsZero);
}];
//textView
[self addSubview:self.textView];
[self.textView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(UIEdgeInsetsZero);
}];
}
#pragma mark - TextViewEdit
-(void)beginEdit{
[self.textView becomeFirstResponder];
}
-(void)endEdit{
[self.textView resignFirstResponder];
}
-(void)clearAll{
2019-01-03 19:16:09 +08:00
_oldLength = 0;
[_valueArr removeAllObjects];
2019-01-03 18:03:44 +08:00
self.textView.text = @"";
2019-01-03 19:16:09 +08:00
[self.mainCollectionView reloadData];
[self triggerBlock];
2019-01-03 18:03:44 +08:00
[self beginEdit];
}
#pragma mark - UITextViewDelegate
-(void)textViewDidChange:(UITextView *)textView{
NSString *verStr = textView.text;
//
verStr = [verStr stringByReplacingOccurrencesOfString:@" " withString:@""];
if (verStr.length >= _codeLength) {
verStr = [verStr substringToIndex:_codeLength];
[self endEdit];
}
textView.text = verStr;
2019-01-03 19:13:36 +08:00
// /
CRBoxTextChangeType boxTextChangeType = CRBoxTextChangeType_NoChange;
if (verStr.length > _oldLength) {
boxTextChangeType = CRBoxTextChangeType_Insert;
}else if (verStr.length < _oldLength){
boxTextChangeType = CRBoxTextChangeType_Delete;
}
2019-01-03 18:03:44 +08:00
// _valueArr
2019-01-03 19:13:36 +08:00
if (boxTextChangeType == CRBoxTextChangeType_Delete) {
[_valueArr removeLastObject];
}else if (boxTextChangeType == CRBoxTextChangeType_Insert){
if (verStr.length > 0) {
2019-01-03 19:39:22 +08:00
if (_valueArr.count > 0) {
[self replaceValueArrToAsteriskWithIndex:_valueArr.count - 1 needEqualToCount:NO];
}
2019-01-03 19:13:36 +08:00
NSString *subStr = [verStr substringWithRange:NSMakeRange(verStr.length - 1, 1)];
[self->_valueArr addObject:subStr];
2019-01-03 19:39:22 +08:00
[self delayAsteriskProcess];
2019-01-03 19:13:36 +08:00
}
}
2019-01-03 18:03:44 +08:00
[_mainCollectionView reloadData];
2019-01-03 19:16:09 +08:00
[self triggerBlock];
_oldLength = verStr.length;
}
- (void)triggerBlock
{
2019-01-03 18:03:44 +08:00
if (self.textDidChangeblock) {
BOOL isFinished = _valueArr.count == _codeLength ? YES : NO;
2019-01-03 19:16:09 +08:00
self.textDidChangeblock(_textView.text, isFinished);
2019-01-03 18:03:44 +08:00
}
2019-01-03 19:13:36 +08:00
}
2019-01-03 19:44:13 +08:00
#pragma mark - Asterisk
2019-01-03 19:39:22 +08:00
// *
- (void)replaceValueArrToAsteriskWithIndex:(NSInteger)index needEqualToCount:(BOOL)needEqualToCount
2019-01-03 19:13:36 +08:00
{
2019-01-03 19:39:22 +08:00
if (needEqualToCount && index != _valueArr.count - 1) {
return;
}
if (_valueArr.count > index && ![_valueArr[index] isEqualToString:@"✱"]) {
[_valueArr replaceObjectAtIndex:index withObject:@"✱"];
}
}
// *
- (void)delayAsteriskProcess
{
__weak typeof(self) weakSelf = self;
2019-01-03 19:44:13 +08:00
[self delayAfter:_securityDelay dealBlock:^{
2019-01-03 19:39:22 +08:00
if (self->_valueArr.count > 0) {
[weakSelf replaceValueArrToAsteriskWithIndex:self->_valueArr.count-1 needEqualToCount:YES];
dispatch_async(dispatch_get_main_queue(), ^{
[self->_mainCollectionView reloadData];
});
2019-01-03 19:13:36 +08:00
}
}];
}
#pragma mark - DelayBlock
- (void)delayAfter:(CGFloat)delayTime dealBlock:(void (^)(void))dealBlock
{
dispatch_time_t timer = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayTime *NSEC_PER_SEC));
dispatch_after(timer, dispatch_get_main_queue(), ^{
if (dealBlock) {
dealBlock();
}
});
2019-01-03 18:03:44 +08:00
}
#pragma mark - UICollectionViewDataSource
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return _codeLength;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CRBoxInputCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CRBoxInputCellID forIndexPath:indexPath];
if (_boxInputCellProperty) {
cell.boxInputCellProperty = _boxInputCellProperty;
}
cell.ifNeedCursor = self.ifNeedCursor;
NSUInteger focusIndex = _valueArr.count;
cell.selected = indexPath.row == focusIndex ? YES : NO;
if (_valueArr.count > 0 && indexPath.row <= focusIndex - 1) {
cell.valueLabel.text = _valueArr[indexPath.row];
}else{
cell.valueLabel.text = @"";
}
return cell;
}
#pragma mark - Setter & Getter
-(UICollectionView *)mainCollectionView
{
if (!_mainCollectionView) {
_mainCollectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:self.boxFlowLayout];
_mainCollectionView.showsHorizontalScrollIndicator = NO;
_mainCollectionView.backgroundColor = [UIColor clearColor];
_mainCollectionView.delegate = self;
_mainCollectionView.dataSource = self;
[_mainCollectionView registerClass:[CRBoxInputCell class] forCellWithReuseIdentifier:CRBoxInputCellID];
}
return _mainCollectionView;
}
-(CRBoxFlowLayout *)boxFlowLayout
{
if (!_boxFlowLayout) {
_boxFlowLayout = [CRBoxFlowLayout new];
_boxFlowLayout.itemSize = CGSizeMake(42, 47);
}
return _boxFlowLayout;
}
- (void)setCodeLength:(NSInteger)codeLength
{
_codeLength = codeLength;
self.boxFlowLayout.itemNum = codeLength;
}
-(void)setKeyBoardType:(UIKeyboardType)keyBoardType{
_keyBoardType = keyBoardType;
self.textView.keyboardType = keyBoardType;
}
2019-01-03 18:43:31 +08:00
-(CRBoxTextView *)textView{
2019-01-03 18:03:44 +08:00
if (!_textView) {
2019-01-03 18:43:31 +08:00
_textView = [CRBoxTextView new];
2019-01-03 18:03:44 +08:00
_textView.tintColor = [UIColor clearColor];
_textView.backgroundColor = [UIColor clearColor];
_textView.textColor = [UIColor clearColor];
_textView.delegate = self;
_textView.keyboardType = UIKeyboardTypeDefault;
}
return _textView;
}
@end