如何更好地限制一个UITextField的输入长度

要限制一个UITextField的输入字数,通过UITextFieldDelegate方法来限制

 // return NO to not change text
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;  

比如要设置字数限制为20:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (textField == self.titleField) {
        if (textField.length > 20) return NO;
    }

    return YES;
}

但是这样的限制简单粗暴,可能会影响用户正常逻辑下的输入,比如输入了20个字符后,要退格回删字符。如果只是这样限制会导致用户无法删除字符,需要加上判断条件:

// 删除一个字符时,string.length == 0,string == @""
// 输入时,string.length才有值
if (string.length == 0) return YES;// return YES 确保能够删除字符

可能还会遇到用户已经输入20个字符了,这时候继续输入,UITextFiled已经无法响应用户的输入了,这也妨碍了用户的正常操作。限制的代码可能会演进为:

#pragma mark - UITextFieldDelegate
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
    
    NSLog(@"range:%@", NSStringFromRange(range));
    NSLog(@"string:%@--length:%zd", string, [string length]);
    NSLog(@"textField.text.length:%zd", textField.text.length);
    NSLog(@"self.textField.text.length:%zd", self.textField.text.length);
    
    if (textField == self.textField) {
         // 删除一个字符时,string.length == 0,string == @""
        // 输入时,string.length才有值
        if (string.length == 0) return YES;// return YES 确保能够删除字符
        
        // 输入时:总长度不包括本次输入的字符长度,总长度为之前输入的总的字符串长度(显示出来的才算)
        // 删除字符时:总长度为删除的字符长度+剩下的字符长度,也就是没删除前textField显示的总长度
        NSInteger existedLength = textField.text.length;
        
        // 删除字符时, range.length才不为0,为删除的字符个数
        // 输入字符状态,那么range.length == 0
        NSInteger selectedLength = range.length;
        
        // 输入时,string.length才有值,输入中文时不调用这个代理方法,就得不到string.length的值
        NSInteger replaceLength = string.length;
        if (existedLength - selectedLength + replaceLength > 20) {
            return NO;
        }
    }
    
    return YES;
}

到这里可能会觉得基本大功告成了,但是当你输入19个字符后,第20个字符以中文汉字的形式继续输入,那么系统会在键盘上方提供后续的一系列联想词,你会发现通过这种方式可以连续选字输入从而突破20个字符的限制,我们可能会希望有个类似UITextView的方法,但事实是没有的,但是有一个通知可以监听到UITextField输入文字的改变

// 自定义的
- (void)textFieldDidChange:(UITextField *)textField

UITextField文字发生改变通知

UIKIT_EXTERN NSString *const UITextFieldTextDidChangeNotification;

监听通知,这样就可以更好地限制输入长度:

[textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

- (void)textFieldDidChange:(UITextField *)textField
{
    if (textField == self.titleField) {
        if (textField.text.length > 20) {
            textField.text = [textField.text substringToIndex:20];
        }
    }
}

参考文章

你可能感兴趣的:(如何更好地限制一个UITextField的输入长度)