Question

I have a UITextField in my application. I'd like to restrict the set of characters that can be can be entered into the field to a set that I have defined. I could filter the characters entered into the field when the text is committed using the UITextFieldDelegate method:

- (BOOL)textFieldShouldReturn:(UITextField*)textField

However, this gives the user a false impression as although restricted characters are removed from the final value, they were still visibly entered into the text field before pressing Return/Done/etc. What is the best approach that would prevent restricted characters appearing in the text field as they are selected on the keyboard?

Note: I am operating under the assumption that I have little control over which keys are provided by the iPhone keyboard(s). I am aware that I can switch between various keyboard implementations but am under the impression that I can't disable specific keys. This assumption may be incorrect.

Was it helpful?

Solution

Look at textField:shouldChangeCharactersInRange

This method is called by the UITextFieldDelegate whenever new characters are typed or existing characters are deleted from the text field. You could return NO to not allow the change.

OTHER TIPS

I did as marcc suggested and it worked well. Sample implementation follows.

Note: Variable names were selected for brevity and do not reflect my coding standards:

    ...
    myCharSet = [NSCharacterSet characterSetWithCharactersInString:@"xyzXYZ"];
    ...
}

- (BOOL) textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)textEntered {
    for (int i = 0; i < [textEntered length]; i++) {
        unichar c = [textEntered characterAtIndex:i];
        if (![myCharSet characterIsMember:c]) {
            return NO;
        }
    }
    return YES;
}

Here is one of the cleanest approaches to restricting characters entered in a UITextField. This approach allows the use of multiple predefined NSCharacterSets.

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{

    NSMutableCharacterSet *allowedCharacters = [NSMutableCharacterSet alphanumericCharacterSet];
    [allowedCharacters formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]];
    [allowedCharacters formUnionWithCharacterSet:[NSCharacterSet symbolCharacterSet]];

    if([string rangeOfCharacterFromSet:allowedCharacters.invertedSet].location == NSNotFound){

        return YES;

    }

    return NO;

}

Look at the UITextViewDelegate method - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string.

It's exactly what you need.

This is what I use to restrict the user to uppercase A-Z. Adjust the regex variable according to taste:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

    NSString* regex = @"[^A-Z]";
    return ([string rangeOfString: regex
                      options:NSRegularExpressionSearch].location == NSNotFound);
};

How about this?

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

    NSString* regex = @"[^a-z]";
    return ([[string lowercaseString] rangeOfString: regex
                      options:NSRegularExpressionSearch].location == NSNotFound);
};

Note:

I am making all characters to lower case [string lowercaseString] so that you don't need to write in regex for captial/small letters.

You could loop and keep checking if the UITextField.text property has changed once the DidBeginEditing method gets called. If it has, check the text and remove an bad characters.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top