How to better limit the input length of a UITextField

To limit the number of input characters in a UITextField (reference link), the first thought should be to pass
UITextFieldDelegate

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

For example, to set the character limit to 20:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (textField == self.titleField) {
        if (textField.length > 20) return NO;
    }

    return YES;
}

However, such restrictions are simple and rude, and may affect the user's input under normal logic. For example, after entering 20 characters, backspace and delete characters are required.
At this time, we may consider "Detect backspace in UITextField", such as simply judging whether the length of replacementString is 0.
Then we may encounter that the user has already entered 20 characters. At this time, the input continues---but some text is selected for replacement---it cannot be carried out, which also hinders the normal operation of the user, so the restriction The code version of may evolve to:
#pragma mark - UITextFieldDelegate

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (textField == self.titleField) {
        if (string.length == 0) return YES;

        NSInteger existedLength = textField.text.length;
        NSInteger selectedLength = range.length;
        NSInteger replaceLength = string.length;
        if (existedLength - selectedLength + replaceLength > 20) {
            return NO;
        }
    }

    return YES;
}

At this point, you may feel that you are basically done, but when you enter 19 characters, the 20th character continues to be entered in the form of Chinese characters, then the system will provide a series of subsequent association words above the keyboard, you will find that through this The method can continuously select words and input to break through the limit of 20 characters. WTF

is here, we might hope for something like
- (void)textFieldDidChange:(UITextField *)textField

The callback method, but unfortunately not.
Of course, we can also
- (void)textFieldDidEndEditing:(UITextField *)textField;

The callback method truncates the text at the end of editing, although it can be a bit obtrusive in terms of user experience.
However, when we click into the UITextField.h header file to find the above callback method and can't find it, we may find that there is such a message notification name at the bottom:
UIKIT_EXTERN NSString *const UITextFieldTextDidChangeNotification;

However, when listening to messages, you have to remember to cancel the monitoring. Usually, I am used to putting the code for monitoring messages in one method, which seems to be a bit of a “big fight”.
Fortunately, UITextField itself provides corresponding event listeners:
[textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

This way you can better limit the input length:
- (void)textFieldDidChange:(UITextField *)textField
{
    if (textField == self.titleField) {
        if (textField.text.length > 20) {
            textField.text = [textField.text substringToIndex:20];
        }
    }
}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326849403&siteId=291194637