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);
    }];
    
    // 设置每个输入框的宽度是40
    CGFloat 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方法focusYES时显示光标,

- (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;
}

猜你喜欢

转载自blog.csdn.net/chennai1101/article/details/130009867