业务需求:
输入手机号,当输入到11位时自动结束第一响应收起键盘
ps:只看最终结果的同学请直接到底部看改进方案2。
思路:
在textField
的代理方法里有
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;
在该方法里判断textField
的长度[1],长度>
11时,结束第一响应。代码如下:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if (range.length + range.location + string.length >= 11) {
[self.textField resignFirstResponder];
[self.view resignFirstResponder];
return NO;
}
return YES;
}
效果1:
分析
可以看到当输入第11
位时,键盘确实收起,达到了业务需求,但是textField
的文本内容还是10
位。
原因是该方法在系统封装好的替换字符串方法之前,而此时结束第一响应,再替换时,第一响应者已经不存在了,所以丢弃了替换方法。因此只需在其中手动加入替换自字符串方法即可。
改进方案1
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if (range.length + range.location + string.length >= 11) {
if (range.length + range.location + string.length == 11) {
NSMutableString *str = [NSMutableString stringWithString:self.textField.text];
[str insertString:string atIndex:range.location];
self.textField.text = str;
}
[self.textField resignFirstResponder];
[self.view resignFirstResponder];
return NO;
}
return YES;
}
效果2:
分析
可以看到输入的问题解决了,但是产生了新的问题:当删除时直接取消了第一响应并且字符串未改变。
改进方案2
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if (![string isEqualToString:@""]) {
if (range.length + range.location + string.length >= 11) {
if (range.length + range.location + string.length == 11) {
NSMutableString *str = [NSMutableString stringWithString:self.textField.text];
[str insertString:string atIndex:range.location];
self.textField.text = str;
}
[self.textField resignFirstResponder];
[self.view resignFirstResponder];
return NO;
}
}
return YES;
}
效果3:
总结
这里只提供了使用代理方法的实现方式,其他还有KVO
等方式也可实现本功能。
补充:
在 iOS10.0 中新增了一个代理方法
- (void)textFieldDidEndEditing:(UITextField *)textField reason:(UITextFieldDidEndEditingReason)reason NS_AVAILABLE_IOS(10_0); // if implemented, called in place of textFieldDidEndEditing:
typedef NS_ENUM(NSInteger, UITextFieldDidEndEditingReason) {
UITextFieldDidEndEditingReasonCommitted,
UITextFieldDidEndEditingReasonCancelled UIKIT_AVAILABLE_TVOS_ONLY(10_0)
} NS_ENUM_AVAILABLE_IOS(10_0);
-
由于该方法是在将要改变时调用,所以 textField 的长度并不能成为最终判断条件,这里使用 range.length + range.location + string.length 来计算最终长度 ↩