版本
Xcode 9.1
基本用法
继承关系:
UITextField : UIControl : UIView : UIResponder : NSObject
示例:
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor lightGrayColor];
/* ----- 初始化 ----- */
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 100, 300, 30)];
textField.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, 100); // 居中
[self.view addSubview:textField]; // 添加至self.view
/* ----- 常用属性 ----- */
// 设置背景颜色
textField.backgroundColor = [UIColor whiteColor];
textField.layer.cornerRadius = 10;
// 设置文字内容
textField.text = @"看影成痴";
// 设置字体颜色
textField.textColor = [UIColor purpleColor];
// 设置字体样式及大小
textField.font = [UIFont systemFontOfSize:18.0];
// 设置对齐方式
textField.textAlignment = NSTextAlignmentCenter;
// 设置边框的样式(cornerRadius将无效)
textField.borderStyle = UITextBorderStyleRoundedRect;
// 设置提示文字
textField.placeholder = @"请输入用户名";
// 设置清空模式,是否每次编辑时都清空一下
textField.clearsOnBeginEditing = YES;
// 自动适应输入框宽度,让输入框可以显示输入的一定数量的所有字体
textField.adjustsFontSizeToFitWidth = YES;
// 设置文字显示的最小字体大小
textField.minimumFontSize = 12;
// 设置可用状态的背景图片(拉伸)
textField.background = [UIImage imageNamed:@""];
// 设置不可用状态的背景图片(拉伸)
textField.disabledBackground = [UIImage imageNamed:@""];
// 设置清理按钮模式
textField.clearButtonMode = UITextFieldViewModeWhileEditing;
// 设置输入框左图
textField.leftView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"left.png"]];
textField.leftView.bounds = CGRectMake(0, 0, 30, 30);
// 左图显示模式(编辑时不显示)
textField.leftViewMode = UITextFieldViewModeUnlessEditing;
// 设置输入框右图
textField.rightView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"right.png"]];
textField.rightView.bounds = CGRectMake(0, 0, 30, 30);
// 右图显示模式
textField.rightViewMode = UITextFieldViewModeUnlessEditing;
// 是否密文输入(输入内容是否可见)
textField.secureTextEntry = NO;
// 设置键盘外观
textField.keyboardAppearance = UIKeyboardAppearanceDark;
// 设置键盘类型
textField.keyboardType = UIKeyboardTypeNumberPad;
// 设置返回键类型
textField.returnKeyType = UIReturnKeyRoute;
// 设置首字母是否大写
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
// 是否自动修正输入内容
textField.autocorrectionType = UITextAutocorrectionTypeDefault;
}
示例效果:
示例中的一些属性枚举:
/* 文字对齐方式 */
typedef NS_ENUM(NSInteger, NSTextAlignment) {
NSTextAlignmentLeft = 0, // 左对齐
#if TARGET_OS_IPHONE // 判断真机or模拟器,我们只管枚举值对应的对齐方式即可
NSTextAlignmentCenter = 1, // 居中(真机)
NSTextAlignmentRight = 2, // 右对齐(真机)
#else /* !TARGET_OS_IPHONE */
NSTextAlignmentRight = 1, // 右对齐(真机)
NSTextAlignmentCenter = 2, // 居中(真机)
#endif
NSTextAlignmentJustified = 3, // 最后一行和段落对齐
NSTextAlignmentNatural = 4, // 默认对齐脚本
} NS_ENUM_AVAILABLE_IOS(6_0);
/* 边框样式 */
typedef NS_ENUM(NSInteger, UITextBorderStyle) {
UITextBorderStyleNone, // 默认样式,无边框
UITextBorderStyleLine, // 边框加黑色线条
UITextBorderStyleBezel, // 边框加灰色线条,上边和左边加重
UITextBorderStyleRoundedRect // 圆角
};
/* 某个属性(譬如删除按钮,leftView)出现时机 */
typedef NS_ENUM(NSInteger, UITextFieldViewMode) {
UITextFieldViewModeNever, // 从不出现
UITextFieldViewModeWhileEditing, // 编辑时出现
UITextFieldViewModeUnlessEditing,// 非编辑时出现
UITextFieldViewModeAlways // 总是出现
};
/* ----- 以下是与 输入内容or键盘 相关属性枚举 ----- */
/* 自动修正内容 */
typedef NS_ENUM(NSInteger, UITextAutocorrectionType) {
UITextAutocorrectionTypeDefault, // 默认,可自动修正
UITextAutocorrectionTypeNo, // 不可修正
UITextAutocorrectionTypeYes, // 可自动修正
};
/* 首字母大写 */
typedef NS_ENUM(NSInteger, UITextAutocapitalizationType) {
UITextAutocapitalizationTypeNone, // 不自动大写
UITextAutocapitalizationTypeWords, // 单词首字母大写
UITextAutocapitalizationTypeSentences, // 句子首字母大写
UITextAutocapitalizationTypeAllCharacters, // 所有字母均大写
};
/* 键盘外观 */
typedef NS_ENUM(NSInteger, UIKeyboardAppearance) {
UIKeyboardAppearanceDefault, // 默认外观,浅灰色
UIKeyboardAppearanceDark, // 深灰色
UIKeyboardAppearanceLight, // 浅灰色
UIKeyboardAppearanceAlert, // 深灰色(已弃用)
};
/* 键盘类型 */
typedef NS_ENUM(NSInteger, UIKeyboardType) {
UIKeyboardTypeDefault, // 默认键盘,支持所有字符
UIKeyboardTypeASCIICapable, // ASCII类型
UIKeyboardTypeNumbersAndPunctuation, // 电话类型,支持+*#
UIKeyboardTypeURL, // URL类型支持 . / .com
UIKeyboardTypeNumberPad, // A number pad with locale-appropriate digits (0-9, ۰-۹, ०-९, etc.). Suitable for PIN entry.
UIKeyboardTypePhonePad, // 电话类型 ,支持0-9, * , #
UIKeyboardTypeNamePhonePad, // 电话类型,支持输入人名
UIKeyboardTypeEmailAddress, // 电子邮件类型,支持空格 @ . 邮件地址
UIKeyboardTypeDecimalPad, // 数字键盘,支持小数点
UIKeyboardTypeTwitter, // 为twitter优化的键盘,更容易输入@ #
UIKeyboardTypeWebSearch, // 为URL优化的键盘,支持空格 . 地址
UIKeyboardTypeASCIICapableNumberPad, // 数字键盘,总是ASCII数字类型(iOS 10.0开始引入)
UIKeyboardTypeAlphabet, // 已弃用
};
/* 键盘的返回键类型 */
typedef NS_ENUM(NSInteger, UIReturnKeyType) {
UIReturnKeyDefault, // 默认,标有Return的灰色按钮
UIReturnKeyGo, // 标有Go的蓝色按钮
UIReturnKeyGoogle, // 标有Google的蓝色按钮
UIReturnKeyJoin, // 标有Join的蓝色按钮
UIReturnKeyNext, // 标有Next的蓝色按钮
UIReturnKeyRoute, // 标有Route的蓝色按钮
UIReturnKeySearch, // 标有Search的蓝色按钮
UIReturnKeySend, // 标有Send的蓝色按钮
UIReturnKeyYahoo, // 标有Yahoo的蓝色按钮
UIReturnKeyDone, // 标有Done的蓝色按钮
UIReturnKeyEmergencyCall, // 紧急呼叫按钮
UIReturnKeyContinue , // 标有Continue的灰色按钮(iOS9.0开始引入)
};
键盘类型图示:
UIKeyboardTypeDefault
UIKeyboardTypeASCIICapable
UIKeyboardTypeNumbersAndPunctuation
UIKeyboardTypeURL
UIKeyboardTypeNumberPad
UIKeyboardTypePhonePad
UIKeyboardTypeNamePhonePad
UIKeyboardTypeEmailAddress
UIKeyboardTypeDecimalPad
UIKeyboardTypeTwitter
UIKeyboardTypeWebSearch
UIKeyboardTypeASCIICapableNumberPad(iOS 10.0开始引入)
收起键盘
收起键盘的两种方法:
- 使用endEditing:方法;
- 注销第一响应者resignFirstResponder
1. endEditing:
在触摸开始方法中,或者添加手势的响应方法中,添加endEditing:
// 触摸开始响应方法
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES]; // 结束视图(或子视图)内所有编辑,即收起键盘
}
2. resignFirstResponder
在按下键盘返回键的代理方法中(这样可以获取相应TextField对象),注销TextField对象第一响应者,将会收起键盘。
/**
按下键盘返回键时
应用举例:调用resignFirstResponder方法收回键盘
@param textField UITextField对象
@return 我发现返回YES或NO,效果都一样...
*/
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder]; // 注销第一响应者,收起键盘
return YES;
}
UITextFieldDelegate
设置TextField的代理后,我们可以跟踪TextField的一些编辑状态,进而处理一些事情。
第一步:遵循代理协议
<UITextFieldDelegate>
第二步:设置代理
textField.delegate = self;
第三步:实现代理方法
#pragma mark - UITextField代理方法
/**
将要开始编辑
@param textField UITextField对象
@return YES:允许编辑; NO:禁止编辑
*/
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
return YES;
}
/**
开始编辑,即成为第一响应者,此时光标出现
@param textField UITextField对象
*/
- (void)textFieldDidBeginEditing:(UITextField *)textField {
NSLog(@"开始编辑");
}
/**
将要结束编辑
应用场景:如果当前TextField有内容,则返回YES,允许收键盘或更换TextField;
当前TextField没有输入内容,返回NO,此时不能收起键盘或者更换TextField
@param textField UITextField对象
@return YES:允许释放键盘(注销第一响应者); NO:不允许释放键盘(始终是第一响应者)
*/
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
// 过滤空格
NSString *strWithoutSpace = [textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if (strWithoutSpace.length == 0) {
return NO;
}
return YES;
}
/**
已经结束编辑
(即使shouldEndEditing方法返回NO或者调用了endEditing:YES,该方法仍可能调用)
官方注释:may be called if forced even if shouldEndEditing returns NO (e.g. view removed from window) or endEditing:YES called
@param textField UITextField对象
*/
- (void)textFieldDidEndEditing:(UITextField *)textField {
NSLog(@"已经结束编辑");
}
/**
已经结束编辑(iOS 10.0开始引入)
如果实现,将取代textFieldDidEndEditing:方法
@param textField UITextField对象
@param reason 结束原因(正常代理结束或者被迫取消)
*/
- (void)textFieldDidEndEditing:(UITextField *)textField reason:(UITextFieldDidEndEditingReason)reason NS_AVAILABLE_IOS(10_0) {
NSLog(@"已经结束编辑(iOS 10.0开始引入)");
}
/**
将要改变文字内容时
应用场景:1.撤销上一次输入
2.跟踪本TextField所做的最后一次修改
3.防止文字被改变
4.限制输入字符类型
@param textField UITextField对象
@param range 被修改内容的范围
@param string 修改内容取代者
@return YES:允许修改; NO:不允许修改
*/
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
return YES;
}
/**
当按下清除按钮时
@param textField UITextField对象
@return YES:允许清除; NO:不许清除
*/
- (BOOL)textFieldShouldClear:(UITextField *)textField {
return YES;
}
/**
按下键盘返回键时
应用举例:调用resignFirstResponder方法收回键盘
@param textField UITextField对象
@return 我发现返回YES或NO,效果都一样...
*/
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
限制UITextField输入字符类型及字符个数
1. 限制输入字符类型
在代理方法中作判断,符合返回YES,不符合返回NO。
例如匹配输入为纯数字:
/**
将要改变文字内容时
应用场景:1.撤销上一次输入
2.跟踪本TextField所做的最后一次修改
3.防止文字被改变
4.限制输入字符类型
@param textField UITextField对象
@param range 被修改内容的范围
@param string 修改内容取代者
@return YES:允许修改; NO:不允许修改
*/
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// 匹配纯数字
NSString *regex = @"[0-9]";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
return [pred evaluateWithObject:string]; // 匹配返回YES,否则返回NO
}
2. 限制输入字符个数
字符个数决定了字符串的长度。
在代理方法中很难实时地获得字符串长度,因此不好在代理方法里判断。好在苹果提供了监听UITextField的编辑发生改变的事件,可在该事件中作判断。
首先要添加事件:
[textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
然后实现事件响应方法:
// 当编辑发生改变
- (void)textFieldDidChange:(UITextField *)textField {
// 获取字符串长度
NSUInteger strLength = 0;
for (NSUInteger i=0; i<textField.text.length; i++) {
unichar uc = [textField.text characterAtIndex: I];
strLength += isascii(uc) ? 1:2; // 汉字两个字节
}
// 如果字符串大于5,裁掉后尾
if (strLength > 5) {
textField.text = [textField.text substringToIndex:5];
}
}
解决键盘遮挡UITextField问题
首先监听键盘显示/收回的系统通知
/* ----- 解决键盘遮挡问题 ----- */
// 监听系统要弹出键盘时,发出该通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
// 监听系统要回收键盘时,发出该通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
实现通知响应方法
#pragma mark - 系统通知调用方法
// 当键盘将要显示时
- (void)keyboardWillShow:(NSNotification *)notification {
// 获取键盘的frame
CGRect keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
// 判断输入框是否被遮挡
NSInteger distance = textField.frame.origin.y + textField.frame.size.height - keyboardRect.origin.y;
if(distance>0) {
// 把界面上移,动画时间0.25s,与键盘同步
[UIView animateWithDuration:0.25 animations:^{
self.view.frame = CGRectMake(0, -distance, self.view.frame.size.width, self.view.frame.size.height);
}];
}
}
// 当键盘将要回收时
- (void)keyboardWillHide:(NSNotification *)notification {
// 背景view恢复原位
self.view.frame = self.view.bounds;
}
对了,既然添加了通知,不要忘了在适当的时候移除哟~
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self]; // 移除通知
}