手把手教你自动取消textField第一响应的设置

业务需求:

输入手机号,当输入到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);

  1. 由于该方法是在将要改变时调用,所以 textField 的长度并不能成为最终判断条件,这里使用 range.length + range.location + string.length 来计算最终长度 ↩

你可能感兴趣的:(手把手教你自动取消textField第一响应的设置)