Вопрос

How would I go about allowing inputting only alphanumeric characters in an iOS UITextField?

Это было полезно?

Решение

Use the UITextFieldDelegate method -textField:shouldChangeCharactersInRange:replacementString: with an NSCharacterSet containing the inverse of the characters you want to allow. For example:

// in -init, -initWithNibName:bundle:, or similar
NSCharacterSet *blockedCharacters = [[[NSCharacterSet alphanumericCharacterSet] invertedSet] retain];

- (BOOL)textField:(UITextField *)field shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)characters
{
    return ([characters rangeOfCharacterFromSet:blockedCharacters].location == NSNotFound);
}

// in -dealloc
[blockedCharacters release];

Note that you’ll need to declare that your class implements the protocol (i.e. @interface MyClass : SomeSuperclass <UITextFieldDelegate>) and set the text field’s delegate to the instance of your class.

Другие советы

This is how I do it:

// Define some constants:
#define ALPHA                   @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
#define NUMERIC                 @"1234567890"
#define ALPHA_NUMERIC           ALPHA NUMERIC

// Make sure you are the text fields 'delegate', then this will get called before text gets changed.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

    // This will be the character set of characters I do not want in my text field.  Then if the replacement string contains any of the characters, return NO so that the text does not change.
    NSCharacterSet *unacceptedInput = nil;

    // I have 4 types of textFields in my view, each one needs to deny a specific set of characters:
    if (textField == emailField) {
        //  Validating an email address doesnt work 100% yet, but I am working on it....  The rest work great!
        if ([[textField.text componentsSeparatedByString:@"@"] count] > 1) {
            unacceptedInput = [[NSCharacterSet characterSetWithCharactersInString:[ALPHA_NUMERIC stringByAppendingString:@".-"]] invertedSet];
        } else {
            unacceptedInput = [[NSCharacterSet characterSetWithCharactersInString:[ALPHA_NUMERIC stringByAppendingString:@".!#$%&'*+-/=?^_`{|}~@"]] invertedSet];
        }
    } else if (textField == phoneField) {
        unacceptedInput = [[NSCharacterSet characterSetWithCharactersInString:NUMERIC] invertedSet];
    } else if (textField == fNameField || textField == lNameField) {
        unacceptedInput = [[NSCharacterSet characterSetWithCharactersInString:ALPHA] invertedSet];
    } else {
        unacceptedInput = [[NSCharacterSet illegalCharacterSet] invertedSet];
    }

    // If there are any characters that I do not want in the text field, return NO.
    return ([[string componentsSeparatedByCharactersInSet:unacceptedInput] count] <= 1);
}

Check out the UITextFieldDelegate Reference too.

I found a simple and working answer and want to share:

connect your UITextField for the event EditingChanged to following IBAction

-(IBAction) editingChanged:(UITextField*)sender
{    
    if (sender == yourTextField)
    {
        // allow only alphanumeric chars
        NSString* newStr = [sender.text stringByTrimmingCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]];

        if ([newStr length] < [sender.text length])
        {
            sender.text = newStr;
        }
    }
}

Swift 3 version

Currently accepted answer approach:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    // Get invalid characters
    let invalidChars = NSCharacterSet.alphanumerics.inverted

    // Attempt to find the range of invalid characters in the input string. This returns an optional.
    let range = string.rangeOfCharacter(from: invalidChars)

    if range != nil {
        // We have found an invalid character, don't allow the change
        return false
    } else {
        // No invalid character, allow the change
        return true
    }
}

Another equally functional approach:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    // Get invalid characters
    let invalidChars = NSCharacterSet.alphanumerics.inverted

    // Make new string with invalid characters trimmed
    let newString = string.trimmingCharacters(in: invalidChars)

    if newString.characters.count < string.characters.count {
        // If there are less characters than we started with after trimming
        // this means there was an invalid character in the input. 
        // Don't let the change go through
        return false
    } else {
        // Otherwise let the change go through
        return true
    }

}

The RegEx way in Swift:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
     if string.isEmpty {
         return true
     }
     let alphaNumericRegEx = "[a-zA-Z0-9]"
     let predicate = NSPredicate(format:"SELF MATCHES %@", alphaNumericRegEx)
     return predicate.evaluate(with: string)
}

For Swift: Connect your UITextField for the event EditingChanged to following IBAction:

@IBAction func ActionChangeTextPassport(sender:UITextField){
    if sender == txtPassportNum{
        let newStr = sender.text?.stringByTrimmingCharactersInSet(NSCharacterSet.alphanumericCharacterSet().invertedSet)
        if newStr?.characters.count < sender.text?.characters.count{
            sender.text = newStr
        }
    }
}

You will have to use the textField delegate methods, and use methods textFieldDidBeginEditing, shouldChangeCharactersInRange and textFieldDidEndEditing to check for the characters.

Please refer to this link for the documentation.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top