2.5 文本输入框控件——UITextField
相比UILabel和UIButton控件,UITextField控件要复杂的多,UITextField是iOS系统中进行文本输入操作的一种UI 控件,用户通过键盘将输入操作传递给UITextField 控件, UITextField控件采用代理的设计模式,再将用户的一些操作用行为以回调方式传递给开发者,最后由开发者来进行具体的逻辑处理。
2.5.1 在屏幕上创建一个输入框
打开Xcode,创建一个名为UITextFIeldTest 的工程,在ViewController.m 文件的viewDidLoad方法中添加如下代码。
- (void)viewDidLoad { [super viewDidLoad]; UITextField * textField = [[UITextField alloc]initWithFrame:CGRectMake (20, 100, 280, 30)]; textField.borderStyle = UITextBorderStyleRoundedRect; textField.placeholder = @"请输入文字"; [self.view addSubview:textField]; }
上面代码创建了一个输入框,UITextField的placeholder属性用于设置提示文字,这些文字在输入框中有输入时会自动隐藏,在输入框输入的内容为空时才会显示出来,其作用主要是用来提示用户此输入框的作用,例如登录界面的用户名输入框通常会这样提示:“请输入您的用户名”。运行工程,会看到如图2-18和图2-19所示的效果。
图2-18 未输入文字的输入框
图2-19 正在输入的输入框
UITextField的borderStyle属性用于设置输入框的界面风格,UITextBorderStyle枚举值的意义如下:
typedef NS_ENUM(NSInteger, UITextBorderStyle) { UITextBorderStyleNone, //无风格 UITextBorderStyleLine, //线性风格 UITextBorderStyleBezel, //bezel风格 UITextBorderStyleRoundedRect //边框风格 };
边框风格的界面效果如图2-18所示,其他风格的输入框界面效果如图2-20~图2-22所示。
图2-20 UITextBorderStyleNone
图2-21 UITextBorderStyleLine
图2-22 UITextBorderStyleBezel
2.5.2 UITextField的常用属性介绍
UITextField中也有相关属性用于输入框中文字属性的设置,代码示例如下:
//设置输入框中文字颜色 textField.textColor = [UIColor redColor]; //设置输入框字体 textField.font = [UIFont systemFontOfSize:14]; //设置文字的对齐模式 textField.textAlignment = NSTextAlignmentCenter;
开发者除了对输入框中文字属性进行设置之外,UITextField 还支持自定义左视图和右视图。UITextField 的左视图应用十分广泛,例如很多密码输入框的左边都会有一个小钥匙的图片,用来提示用户输入框的作用。设置左视图的代码示例如下:
UIImageView * imageView = [[UIImageView alloc]initWithImage:[UIImage i mageNamed:@"image"]]; textField.leftView = imageView; textField.leftViewMode = UITextFieldViewModeAlways;
UITextField的leftView属性需要传入一个UIView或者其子类的对象,示例代码中使用了UIImageView, leftViewMode属性设置了显示左视图的显示模式,枚举意义如下:
typedef NS_ENUM(NSInteger, UITextFieldViewMode) { UITextFieldViewModeNever, //从不显示 UITextFieldViewModeWhileEditing, //编辑时显示 UITextFieldViewModeUnlessEditing, //非编辑时显示 UITextFieldViewModeAlways //总是显示 };
此时运行工程,可以看到如图2-23的界面效果。
图2-23 显示左视图的UITextField
提示
UIImageView 是专门用来展示图片的视图类。其不仅可以通过设置image属性进行图片的渲染展示,还可以通过一些设置实现帧动画的播放。
2.5.3 UITextField的代理方法
在本章的开头部分,介绍了代理这种设计模式,UITextField 的一些回调就是通过代理来实现的。例如很多网站的会员账号是采用手机号来注册的,这时对于用户名输入框来说,其只能允许用户输入不超过11位的数字,如果用户输入非数字字符或者输入超限,应用会进行处理,使用户的这次输入无效。其实这个过程就是一个代理回调的过程,首先用户输入一个字符,字符被传进UITextField中,UITextField无法判断这个字符是否有效,它将字符通过代理再传递给开发者,开发者来做逻辑处理。UITextFieldDelegate中支持以下这些代理方法:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField; //当输入框将 要开始编辑时系统自动回调的方法 - (void)textFieldDidBeginEditing:(UITextField *)textField; //当输入框已 经开始编辑时系统自动回调的方法 - (BOOL)textFieldShouldEndEditing:(UITextField *)textField; //输入框将要结 束编辑模式时系统自动回调的方法 - (void)textFieldDidEndEditing:(UITextField *)textField; //输入框已经结束 编辑模式时系统自动回调的方法 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange: (NSRange)range replacementString:(NSString *)string; // 输入框中内容将要改变时 系统自动回调的方法 - (BOOL)textFieldShouldClear:(UITextField *)textField; //输入框中内容将 要被清除时系统自动回调的方法 - (BOOL)textFieldShouldReturn:(UITextField *)textField; //用户单击键盘re turn键后系统自动回调的方法
textFieldShouldBeginEditing:方法是当用户在屏幕上单击输入框,键盘将要弹出来时会调用。这个函数有一个BOOL类型的返回值,如果开发者在实现这个函数时返回NO,则键盘不会弹出来,UITextFiled 控件也不能进入编辑状态。textFiedShouldEndEditing:方法与textFieldShouldBeginEditing:方法类似,只是它对应的是结束编辑状态。textFieldDidBeginEditing:方法和textFieldDidEndEditing:方法分别是在UITextField已经开始和已经结束编辑状态时触发的方法。shouldChangeCharactersInRange:replacementString:方法在输入框中内容将要改变时会调用,其内会传进两个参数给开发者使用,range是将要改变的字符范围,string是将要替换成的字符串,同时这个函数还需要返回一个BOOL类型的返回值,如果返回NO,则这次字符改变行为则不成功,判断用户的输入是否合法的操作,一般会放在这个代理方法中进行。textFieldShouldClear:方法在单击清除按钮后会被调用,这里的返回值如果返回NO,则这次清除操作无效。textFieldShouldReturn:方法在用户单击键盘上的return按钮后进行调用。
提示
所谓UITextField 的编辑状态,就是光标出现在输入框中并且闪烁,键盘弹出等待用户输入的状态。
2.5.4 实现一个监听输入信息的用户名输入框
上面介绍了UITextFieldDelegate中的相关方法,有了这些知识,已经可以实现一个实时监听的输入框了,要使用代理方法需要3个步骤:
(1)遵守相应协议
(2)设置代理
(3)实现代理方法
首先,在类的声明部分添加要遵守的代理,如下所示。
@interface ViewController ()<UITextFieldDelegate> @end
在viewDidLoad方法中添加如下一行代码进行代理的设置。
textField.delegate = self;
在ViewController.m文件中实现如下的代理方法。
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange: (NSRange)range replacementString:(NSString *)string{ if (string.length>0) { if ([string characterAtIndex:0]<'0'||[string characterAtIndex:0]>'9') { NSLog(@"请输入数字"); return NO; } if (textField.text.length+string.length>11) { NSLog(@"超过11位啦"); return NO; } } return YES; }
在实现的textField:shouldChangeCharactersInRange:replacementString:方法中,先进行了是否是数字的逻辑判断。如果不是数字,则会打印提示信息,并且使本次输入无效,之后判断数字是否超过11位,这个判断条件中取的字符长度是输入框上原有文字的长度加上本次输入的字符的长度,如果超过11位,进行打印信息并使本次输入无效。这样,一个只能输入数字且不可超过11位的输入框就编写完成了,如图2-24所示。
图2-24 监听用户输入操作的UITextField