iOS开发 oc 如何设计并实现验证码6个方格的输入,每输入一个数字时当前方格的边框为红色,其他方格的边框置为灰,且输入框的文字颜色为黑色

124 阅读2分钟

为了实现一个iOS开发中的6个方格验证码输入框,并且每输入一个数字时当前方格的边框变为红色,我们可以参考上述我搜索到的资料,结合其中的有效信息来设计和实现这个功能。以下是一个详细的实现步骤和代码示例。

实现步骤

  1. 创建自定义视图类:创建一个继承自UIView的自定义视图类,用于容纳6个UITextField。
  2. 初始化UITextField:在自定义视图类中初始化6个UITextField,并设置它们的样式和位置。
  3. 设置代理:设置每个UITextField的代理为自定义视图类,以便监听输入事件。
  4. 处理输入事件:在代理方法中处理输入事件,当用户输入一个数字时,改变当前UITextField的边框颜色为红色。
  5. 自动跳转:当用户在一个UITextField中输入一个数字后,自动将焦点移动到下一个UITextField。

代码示例

CustomVerificationCodeView.h

#import <UIKit/UIKit.h>

@interface CustomVerificationCodeView : UIView

@property (nonatomic, copy) void (^onCompletion)(NSString *code); // 输入完成回调

@end

CustomVerificationCodeView.m

#import "CustomVerificationCodeView.h"

@interface CustomVerificationCodeView ()

@property (nonatomic, strong) NSMutableArray<UITextField *> *textFields;

@end

@implementation CustomVerificationCodeView

- (instancetype)initWithFrame:(CGRect)frame {

self = [super initWithFrame:frame];

if (self) {

[self setupView];

}

return self;

}

- (void)setupView {

self.textFields = [NSMutableArray array];

NSInteger count = 6; // 6个验证码格子

CGFloat spacing = 10;

CGFloat width = 40;

CGFloat height = 50;

// 计算总宽度并居中布局

CGFloat totalWidth = (width * count) + (spacing * (count - 1));

CGFloat startX = (self.frame.size.width - totalWidth) / 2;

for (NSInteger i = 0; i < count; i++) {

UITextField *textField = [[UITextField alloc] init];

textField.frame = CGRectMake(startX + i * (width + spacing), 0, width, height);

// ---基础样式---

textField.borderStyle = UITextBorderStyleNone; // !!!关键点:必须禁用系统边框!!!

textField.backgroundColor = [UIColor lightGrayColor]; //浅灰背景

textField.textAlignment = NSTextAlignmentCenter; //居中显示

// ---文字样式---

textField.textColor = UIColor.blackColor; //黑色文字

textField.font = [UIFont boldSystemFontOfSize:24];//大号加粗字体

// ---边框样式---

textField.layer.cornerRadius = 4; //圆角4pt

textField.layer.masksToBounds = YES;

/* !!!核心逻辑!!!

初始状态:

-所有格子默认灰色边框

-只有第一个格子高亮(如果设计需要)

*/

textField.layer.borderWidth = 1;

textField.layer.borderColor =(i==0)? [UIColor redColor].CGColor : [UIColor lightGrayColor].CGColor;

/* ---交互配置--- */

textField.keyboardType = UIKeyboardTypeNumberPad;//数字键盘

textField.delegate = self; //设置代理

textField.tag = i; //标记索引

/* ---添加到视图--- */

[self addSubview:textField];

[self.textFields addObject:textField];

}

}

#pragma mark - UITextFieldDelegate

/* !!!核心逻辑:处理文本变化!!! */

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

/* ---规则1:只允许数字输入--- */

NSCharacterSet* notDigits=[[NSCharacterSet decimalDigitCharacterSet] invertedSet];

if([string rangeOfCharacterFromSet:notDigits].location!=NSNotFound){

return NO;

}

/* ---规则2:处理有效输入--- */

if(string.length>0 && range.length==0){

/* Step1:更新当前文本框内容 */

textField.text=string;

/* Step2:更新所有文本框的边框状态 */

[self updateAllBordersWithActiveIndex:textField.tag];

/* Step3:自动跳转逻辑 */

if(textField.tag<_textFields.count-1){

[_textFields[textField.tag+1] becomeFirstResponder];

}else{

/* ---触发完成回调--- */

if(_onCompletion){

_onCompletion([self currentVerificationCode]);

}

[textField resignFirstResponder];

}

}else if(string.length==0 && range.length>0){

/* ---处理删除操作--- */

textField.text=@"";

/* ---更新边框状态--- */

[self updateAllBordersWithActiveIndex:MAX(0, textField.tag-1)];

/* ---跳转到上一个文本框--- */

if(textField.tag>0){

[_textFields[textField.tag-1] becomeFirstResponder];

}

}

return NO;//重要!必须返回NO以禁止系统默认处理

}

//* !!!核心方法:统一更新所有边框状态!!! */

-(void)updateAllBordersWithActiveIndex:(NSInteger)activeIndex{

[self.textFields enumerateObjectsUsingBlock:^(UITextField* tf,NSUInteger idx,BOOL*stop){

/* ---规则--- */

BOOL isActive=(idx==activeIndex); //是否当前活跃格子

/* ---动态设置--- */

tf.layer.borderWidth= isActive ?2:1;//活跃格子加粗边框

tf.layer.borderColor=(isActive)? [UIColor redColor].CGColor : [UIColor lightGrayColor].CGColor;

}];

}

/* ---获取当前验证码字符串--- */

-(NSString*)currentVerificationCode{

NSMutableString* code=[NSMutableString string];

for(UITextField* tf in self.textFields){

[code appendString:tf.text?:@""];//nil保护

}

return code.copy;

}

/* ---开始编辑时的高亮处理--- */

-(void)textFiledDidBeginEditing:(UITextField*)textFiled{

/* ---确保只有当前编辑的文本框高亮--- */

[self.textFields enumerateObjectsUsingBlock:^(UITextField* tf,NSUInteger idx,BOOL*stop){

BOOL isCurrent=(tf==textFiled);

tf.layer.borderWidth= isCurrent?2:1;

tf.layer.borderColor= isCurrent? [UIColor redColor].CGColor : [UIColor lightGrayColor].CGColor;

}];

}

@end

使用示例

在你的视图控制器中使用这个自定义视图类:

#import "ViewController.h"

#import "CustomVerificationCodeView.h"

@interface ViewController ()

@property (nonatomic, strong) CustomVerificationCodeView *verificationCodeView;

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

self.verificationCodeView = [[CustomVerificationCodeView alloc] initWithFrame:CGRectMake(50, 100, self.view.frame.size.width - 100, 50)];

[self.view addSubview:self.verificationCodeView];

}

@end

总结

以上代码实现了一个包含6个方格的验证码输入框,每个方格在用户输入数字时边框变为红色,并且会自动跳转到下一个方格。你可以根据需要进一步调整样式和功能。希望这个示例对你有所帮助!