六位验证码独立输入-TextField
当前我们很多 app 都有六位密码输入的界面,如常见的 支付宝 微信 以及 各家银行类 app 等等。
这次公司项目也有一个类似的界面,是输入验证码,而且输入框的 layer 还会根据是否输入的状态来改变。
我打算直接用 TextField 来写一个,由于是第一次写所以判断的逻辑和代码比较复杂,后续有机会会有优化。
思路及部分代码展示
自定义 TextField.h:
@class CertificatePasswordTextField;
@protocol CPTextFieldDelegate <NSObject>
- (void)cpTextFieldDeleteBackward:(CertificatePasswordTextField *)textField;
@end
@interface CertificatePasswordTextField : UITextField
@property (nonatomic, assign) id <CPTextFieldDelegate> cp_delegate;
@end
自定义 TextField.m:
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.textAlignment = NSTextAlignmentCenter;
self.keyboardType = UIKeyboardTypeNumberPad;
[self setTintColor:[UIColor clearColor]]; // 光标隐藏,可根据需要设置
self.alpha = 0.3;
self.layer.cornerRadius = 5;
self.layer.borderWidth = 1;
self.layer.borderColor = [UIColor blueColor].CGColor;
}
return self;
}
- (void)deleteBackward {
[super deleteBackward];
if ([self.cp_delegate respondsToSelector:@selector(cpTextFieldDeleteBackward:)]) {
[self.cp_delegate cpTextFieldDeleteBackward:self];
}
}
controller中代码 (部分)
@interface ViewController ()<UITextFieldDelegate, CPTextFieldDelegate>
@property (nonatomic, strong) CertificatePasswordTextField *oneText;
@property (nonatomic, strong) CertificatePasswordTextField *twoText;
@property (nonatomic, strong) CertificatePasswordTextField *threeText;
@property (nonatomic, strong) CertificatePasswordTextField *fourText;
@property (nonatomic, strong) CertificatePasswordTextField *fiveText;
@property (nonatomic, strong) CertificatePasswordTextField *sixText;
@property (nonatomic, strong) NSMutableArray *passwordArray;
@end
#pragma mark - CP Text Field Delegate
- (void)cpTextFieldDeleteBackward:(CertificatePasswordTextField *)textField {
// 若输入中断再次输入时可以立即定位并唤起正确第一响应者
if ([textField.text isEqualToString:@""]) {
textField.text = @"";
if ([textField isEqual:self.sixText]) {
[self.fiveText becomeFirstResponder];
} else if ([textField isEqual:self.fiveText]) {
[self.fourText becomeFirstResponder];
} else if ([textField isEqual:self.fourText]) {
[self.threeText becomeFirstResponder];
} else if ([textField isEqual:self.threeText]) {
[self.twoText becomeFirstResponder];
} else if ([textField isEqual:self.twoText]) {
[self.oneText becomeFirstResponder];
}
}
}
#pragma mark - Text Field Delegate
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
// 若当前 textfield 有输入内容则变色
if ([textField isEqual:self.oneText] && self.twoText.text.length < 1) {
textField.alpha = 1;
return YES;
} else if ([textField isEqual:self.twoText] && self.threeText.text.length < 1) {
if (self.oneText.text.length > 0) {
textField.alpha = 1;
return YES;
}
} else if ([textField isEqual:self.threeText] && self.fourText.text.length < 1) {
if (self.twoText.text.length > 0) {
textField.alpha = 1;
return YES;
}
} else if ([textField isEqual:self.fourText] && self.fiveText.text.length < 1) {
if (self.threeText.text.length > 0) {
textField.alpha = 1;
return YES;
}
} else if ([textField isEqual:self.fiveText] && self.sixText.text.length < 1) {
if (self.fourText.text.length > 0) {
textField.alpha = 1;
return YES;
}
} else if ([textField isEqual:self.sixText]) {
if (self.fiveText.text.length > 0) {
textField.alpha = 1;
return YES;
}
}
return NO;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
// 根据输入判断是否改变 layer 颜色
if (textField.text.length > 0) {
textField.alpha = 1;
} else {
textField.alpha = 0.3;
}
if (textField.text.length > 1) {
// 经测试 iOS13 以上在通过键盘一次性多位输入会出现第一个 TexitField 多位输入
textField.text = [textField.text substringWithRange:NSMakeRange(0, 1)];
}
return YES;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField.text.length < 1 || [string isEqualToString:@""]) {
// 对 textfield 应位 array 输入记录
if ([textField isEqual:self.oneText]) {
[self.passwordArray replaceObjectAtIndex:0 withObject:string];
} else if ([textField isEqual:self.twoText]) {
[self.passwordArray replaceObjectAtIndex:1 withObject:string];
} else if ([textField isEqual:self.threeText]) {
[self.passwordArray replaceObjectAtIndex:2 withObject:string];
} else if ([textField isEqual:self.fourText]) {
[self.passwordArray replaceObjectAtIndex:3 withObject:string];
} else if ([textField isEqual:self.fiveText]) {
[self.passwordArray replaceObjectAtIndex:4 withObject:string];
} else if ([textField isEqual:self.sixText]) {
[self.passwordArray replaceObjectAtIndex:5 withObject:string];
}
return YES;
}
// 若输入中断再次输入时可以立即定位并唤起正确第一响应者
if ([textField isEqual:self.oneText]) {
self.twoText.text = string;
[self.twoText becomeFirstResponder];
} else if ([textField isEqual:self.twoText]) {
self.threeText.text = string;
[self.threeText becomeFirstResponder];
} else if ([textField isEqual:self.threeText]) {
self.fourText.text = string;
[self.fourText becomeFirstResponder];
} else if ([textField isEqual:self.fourText]) {
self.fiveText.text = string;
[self.fiveText becomeFirstResponder];
} else if ([textField isEqual:self.fiveText]) {
self.sixText.text = string;
[self.sixText becomeFirstResponder];
}
return NO;
}
至此,主要的核心代码及实录已经展示完毕,下面来看一下最终效果图:
不看代码的话效果非常不错!
本文源码:CurrentDateChooseDatePicker
欢迎大家提问指教!