iOS 自定义验证码输入框
1. 自定义手机验证码
自定义手机验证码,效果如下
2. UKMobileVerifyView控件
UKMobileVerifyView
控件由两部分组成,
- 接收键盘输入的
UITextField
- 显示输入效果的
UKMobileVerifyItemView
- (void)setupInitialUI {// inputTextFiled用来接收键盘输入[self addSubview:self.inputTextField];[self.inputTextField mas_makeConstraints:^(MASConstraintMaker *make) {make.left.right.top.bottom.equalTo(self);}];// contentView用来遮盖输入框[self addSubview:self.contentView];[self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {make.left.right.top.bottom.equalTo(self);}];// 设置每个输入框的宽度是40CGFloat itemWidth = 40;CGFloat itemHeight = self.frame.size.height;CGFloat itemPadding = (self.frame.size.width - 160)/3;self.itemViewArray = @[[self itemViewWithFrame:CGRectMake(0, 0, itemWidth, itemHeight)],[self itemViewWithFrame:CGRectMake(itemWidth+itemPadding, 0, itemWidth, itemHeight)],[self itemViewWithFrame:CGRectMake((itemWidth+itemPadding)*2, 0, itemWidth, itemHeight)],[self itemViewWithFrame:CGRectMake((itemWidth+itemPadding)*3, 0, itemWidth, itemHeight)]];// 初始化四个显示框for (UKMobileVerifyItemView *itemView in self.itemViewArray) {[self.contentView addSubview:itemView];}
}- (UITextField *)inputTextField {if (!_inputTextField) {_inputTextField = [[UITextField alloc] init];_inputTextField.keyboardType = UIKeyboardTypeNumberPad;_inputTextField.autocorrectionType = UITextAutocorrectionTypeNo;_inputTextField.autocapitalizationType = UITextAutocapitalizationTypeNone;_inputTextField.delegate = self;}return _inputTextField;
}- (UIView *)contentView {if (!_contentView) {_contentView = [[UIView alloc] init];_contentView.backgroundColor = [UIColor whiteColor];// 点击contentView可以重新获取焦点UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onContentAction:)];[_contentView addGestureRecognizer:recognizer];}return _contentView;
}- (void)onContentAction:(UITapGestureRecognizer *)recognizer {[self.inputTextField becomeFirstResponder];
}- (UKMobileVerifyItemView *)itemViewWithFrame:(CGRect)frame {return [[UKMobileVerifyItemView alloc] initWithFrame:frame];
}- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];NSArray *array = [string componentsSeparatedByCharactersInSet:set];// 限制只能输入数字if ([@"" isEqualToString:[array componentsJoinedByString:@""]]) {NSMutableString *text = [[NSMutableString alloc] initWithString:textField.text];[text replaceCharactersInRange:range withString:string];// 限制输入数量if (text.length > [self.itemViewArray count]) {return false;}// 显示输入内容[self setSelection:text];// 输入完成if (text.length == [self.itemViewArray count] && self.delegate) {[self.delegate mobileVerifyDidFinish:text];}return true;}return false;
}- (void)setSelection:(NSString *)text {NSInteger len = text.length;// 设置显示值 for (int index = 0; index < [self.itemViewArray count]; index++) {UKMobileVerifyItemView *itemView = self.itemViewArray[index];if (index < len) {[itemView setText:[text substringWithRange:NSMakeRange(index, 1)]];} else {[itemView setText:@""];}[itemView setFocus:NO];}// 显示光标规则// 1. 如果输入位数小于最大位数,光标显示在输入位数+1// 2. 如果输入位数等于最大位数,贯标显示在最大位数if (len < [self.itemViewArray count]) {UKMobileVerifyItemView *itemView = self.itemViewArray[len];[itemView setFocus:YES];} else {UKMobileVerifyItemView *itemView = [self.itemViewArray lastObject];[itemView setFocus:YES];}
}
3. UKMobileVerifyItemView控件
UKMobileVerifyItemView
主要由三部分组成,输入值、光标和下面的显示条
- (void)setupInitialUI {[self addSubview:self.textLabel];[self.textLabel mas_makeConstraints:^(MASConstraintMaker *make) {make.center.equalTo(self);}];[self addSubview:self.cursorView];[self.cursorView mas_makeConstraints:^(MASConstraintMaker *make) {make.width.equalTo(@2);make.height.equalTo(@20);make.center.equalTo(self);}];[self addSubview:self.indicatorView];[self.indicatorView mas_makeConstraints:^(MASConstraintMaker *make) {make.left.right.bottom.equalTo(self);make.height.equalTo(@1.5);}];
}- (UILabel *)textLabel {if (!_textLabel) {_textLabel = [[UILabel alloc] init];_textLabel.textColor = UIColor.blackColor;[_textLabel setFont:[UIFont boldSystemFontOfSize:22]];_textLabel.textAlignment = NSTextAlignmentCenter;}return _textLabel;
}- (UIView *)cursorView {if (!_cursorView) {_cursorView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 2, 20)];[_cursorView.layer addSublayer:self.cursorLayer];}return _cursorView;
}// cursorLayer用来显示光标
- (CALayer *)cursorLayer {if (!_cursorLayer) {_cursorLayer = [CALayer layer];_cursorLayer.frame = CGRectMake(0, 0, 2, 20);_cursorLayer.backgroundColor = UIColor.blueColor.CGColor;_cursorLayer.opacity = 0;}return _cursorLayer;
}- (UIView *)indicatorView {if (!_indicatorView) {_indicatorView = [[UIView alloc] init];_indicatorView.backgroundColor = UIColor.lightGrayColor;}return _indicatorView;
}
setText:(NSString)text
显示输入值,setFocus:(Boolean)focus
方法focus
为YES
时显示光标,
- (void)setText:(NSString *)text {self.textLabel.text = text;
}- (void)setFocus:(BOOL)focus {if (focus) {// 显示光标,如果有没有输入值,居中显示,如果有输入值,并排显示[self.cursorLayer addAnimation:self.animation forKey:@"keypath_opacity"];if ([self.textLabel.text length] > 0) {[self.cursorView mas_updateConstraints:^(MASConstraintMaker *make) {make.centerX.equalTo(self).offset(10);}];} else {[self.cursorView mas_updateConstraints:^(MASConstraintMaker *make) {make.centerX.equalTo(self);}];}// 修改下面显示条颜色self.indicatorView.backgroundColor = UIColor.blueColor;} else {// 不显示光标,默认是透明色[self.cursorLayer removeAnimationForKey:@"keypath_opacity"];// 下面显示条默认是灰色self.indicatorView.backgroundColor = UIColor.lightGrayColor;}
}// 光标显示动画
- (CAKeyframeAnimation *)animation {if (!_animation) {_animation = [[CAKeyframeAnimation alloc] init];_animation.keyPath = @"opacity";_animation.repeatCount = MAXFLOAT;_animation.duration = 1.5;_animation.keyTimes = @[@(0), @(0.4), @(0.45), @(1)];_animation.values = @[@(1), @(1), @(0), @(0)];}return _animation;
}