简体   繁体   中英

How to disable letter characters in UITextField?

In my application i need to allow users input only numbers. How can i allow UITextField to receive only numbers from user?

The characters in this examples are allowed, so if you dont want the user to use a character, exclude it from myCharSet .

- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{
    NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
    for (int i = 0; i < [string length]; i++) {
        unichar c = [string characterAtIndex:i];
        if (![myCharSet characterIsMember:c]) {
            return NO;
        }
    }

    return YES;
} 

I prefer the following solution that actually prevents any any input except from numbers and backspace. Backspace for some reason is represented by an empty string and could not be used unless empty string returns YES. I also popup an alert view when the user enters a character other that numbers.

- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{
    if (string.length == 0) {
        return YES;
    }
    NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
    for (int i = 0; i < [string length]; i++) {
        unichar c = [string characterAtIndex:i];
        if ([myCharSet characterIsMember:c]) {
            return YES;
        }
    }
    UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Invalid Input" message:@"Only numbers are allowed for participant number." delegate:self cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
    [av show];
    return NO;
}

This is perhaps the cleanest, simplest solution to allow only positive or negative numbers. This also allows backspace.

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

    NSCharacterSet *allowedCharacters = [NSCharacterSet characterSetWithCharactersInString:@"-0123456789"];

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

        return YES;

    }

    return NO;

}

you guys might flame.. but this worked for me.. only numbers (including negatives), and backspace.

NSCharacterSet *validCharSet;

if (range.location == 0) 
    validCharSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789-."];
else
    validCharSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789."];

if ([[string stringByTrimmingCharactersInSet:validCharSet] length] > 0 ) return NO;  //not allowable char


NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];

NSNumber* candidateNumber;

NSString* candidateString = [textField.text stringByReplacingCharactersInRange:range withString:string];

range = NSMakeRange(0, [candidateString length]);

[numberFormatter getObjectValue:&candidateNumber forString:candidateString range:&range error:nil];

if  (candidateNumber == nil ) {

    if  (candidateString.length <= 1) 
        return YES;
    else
        return NO;
}

return YES;

Here is my solution applying algebra of sets with the method isSupersetOfSet: This also doesn't allow pasting text with invalid characters:

- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (string.length == 0 || [_numericCharSet isSupersetOfSet:[NSCharacterSet characterSetWithCharactersInString:string]]) {
        return YES;
    }
    else {
        UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Invalid Input"
                                                     message:@"Only numeric input allowed."
                                                    delegate:self
                                           cancelButtonTitle:@"Close"
                                           otherButtonTitles:nil];
        [av show];
        return NO;
    }
}

Note: according to Apple Developer Library , It's preferable cache the static NSCharacterSet than to create it again and again (here _numericCharSet ).

However I prefer to let the user to input any character and validate the value in the method textFieldShouldEndEditing: called when the textField tries to resign first responder. In this manner the user can paste any text (maybe composed with a mix of letters and numbers) and tidy up it in my textFields. The users do not like to see limited their actions.

In Swift

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if textField.tag == 2 {  //your textField
        let invalid = NSCharacterSet(charactersInString: "aeiou")  //characters to block
        if let range = string.rangeOfCharacterFromSet(invalid) {
            return false
        }
    }

    return true
}

您可以做的一件事是显示数字键盘和文本字段旁边或其他一些地方添加动态按钮来隐藏键盘。

Here is a swift example

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

    var disabledCharacters:NSCharacterSet = NSCharacterSet(charactersInString: "0123456789")
        for (var i:Int = 0; i < count(string); ++i) {
            var c = (string as NSString).characterAtIndex(i)
            if (disabledCharacters.characterIsMember(c)) {
                println("Can't use that character dude :/")
                return false
            }
        }

    return true
}

Don't forget to add UITextFieldDelegate to your UIViewController as well.

This thread is a little old, but for the sake of reference I am going to leave a solution in swift 3. This solution will combine decimalDigits and the actual decimal. You can put together whatever combination you'd like, but for my case this is what the requirements were.

// instantiate a mutable character set
let characterSet = NSMutableCharacterSet()
// assign the needed character set
characterSet.formUnion(with: NSCharacterSet.decimalDigits)
// only need the decimal character added to the character set
characterSet.addCharacters(in: ".")
// invert and return false if it's anything other than what we're looking for
if string.rangeOfCharacter(from: characterSet.inverted) != nil {
    return false
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    char *x = (char*)[string UTF8String];
    //NSLog(@"char index is %i",x[0]);
    if([string isEqualToString:@"-"] || [string isEqualToString:@"("] || [string isEqualToString:@")"] || [string isEqualToString:@"0"] || [string isEqualToString:@"1"] ||  [string isEqualToString:@"2"] ||  [string isEqualToString:@"3"] ||  [string isEqualToString:@"4"] ||  [string isEqualToString:@"5"] ||  [string isEqualToString:@"6"] ||  [string isEqualToString:@"7"] ||  [string isEqualToString:@"8"] ||  [string isEqualToString:@"9"] || x[0]==0 || [string isEqualToString:@" "]) {

    NSUInteger newLength = [textField.text length] + [string length] - range.length;
    return (newLength > 14) ? NO : YES;
} else {
    return NO;
}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM