16

I have a UITextField in my IB and I want to check out if the user entered only numbers (no char)and get the integer value.

I get the integer value of the UITextField like that :

int integer = [myUITexrtField.text intValue];

When I put a character ( , ; . ) it return me 0 and I don't know how to detect that it is not only numbers.

How can I do?

Raphael Pinto
  • 279
  • 1
  • 3
  • 13

9 Answers9

49

Implementing shouldChangeCharactersInRange method as below does not allow the user input non-numeric characters.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 
    NSCharacterSet *nonNumberSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
    return ([string stringByTrimmingCharactersInSet:nonNumberSet].length > 0) || [string isEqualToString:@""];
}

This returns YES if the string is numeric, NO otherwise. the [string isEqualToString@""] is to support the backspace key to delete.

I love this approach because it's clean.

DiscDev
  • 38,652
  • 20
  • 117
  • 133
aslı
  • 8,740
  • 10
  • 59
  • 80
  • 9
    To enable delete: return ([string stringByTrimmingCharactersInSet:nonNumberSet].length > 0) || [string isEqualToString:@""]; – andershqst Jan 23 '12 at 19:07
  • 7
    Only problem is if a user paste in a string e.g. 1n1a, stringByTrimmingCharactersInSet: will only remove from start and end of the string. Do something like: NSRegularExpression *numbersOnly = [NSRegularExpression regularExpressionWithPattern:@"[0-9]+" options:NSRegularExpressionCaseInsensitive error:&error]; NSInteger numberOfMatches = [numbersOnly numberOfMatchesInString:string options:0 range:NSMakeRange(0, string.length)]; if (numberOfMatches != 1 && string.length != 0) { shouldChange = NO; } – mbogh Jul 09 '12 at 11:24
  • @mbogh 's comment should be the answer. – septerr Jan 03 '14 at 20:27
  • Alternatively, you could change the second line to `return [string stringByTrimmingCharactersInSet:numbers].length == string.length;` – Jason Apr 22 '15 at 20:49
17

Be sure to set your text field delegate

Use the following function to ensure user can type in numbers only:

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

    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 (([candidateString length] > 0) && (candidateNumber == nil || range.length < [candidateString length])) {

        return NO;
    }
    else 
    {
        return YES;
    }
}
Marichka
  • 397
  • 1
  • 3
  • 1
    This does not work if the first character typed is a letter. If a number is typed first, then a letter is typed it works, however. – GarethPrice Sep 24 '11 at 01:59
9

Try this: It will stop user to enter any character other then numbers

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSCharacterSet *nonNumberSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];

   if ([string rangeOfCharacterFromSet:nonNumberSet].location != NSNotFound) 
   {
       return NO;
   }
   return YES;
}
Fauad Anwar
  • 91
  • 2
  • 3
  • 1
    An answer was provided and accepted 2 years ago. Please do not answer such old questions which have already been answered unless you have something substantive to add. – mah Oct 09 '12 at 13:49
  • What does your answer adds to the previous ones? Why it is valuable and you think should be an answer? There are already several high upvoted answers to this question, why your is different? – Yaroslav Oct 09 '12 at 13:50
  • 1
    this was a very quick solution to implement. don't forget to add the textField delegate to the .h file – Christian Loncle Jan 09 '13 at 08:44
4

http://rosettacode.org/wiki/Determine_if_a_string_is_numeric#Objective-C

Or you could ensure that only the numeric keyboard appears when the focus comes on the field

Liam
  • 7,762
  • 4
  • 26
  • 27
3

To only allow for numeric input:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 
    return [string isEqualToString:@""] || 
        ([string stringByTrimmingCharactersInSet:
            [[NSCharacterSet decimalDigitCharacterSet] invertedSet]].length > 0);
}

To test for an integer:

- (BOOL)isNumeric:(NSString *)input {
    for (int i = 0; i < [input length]; i++) {
        char c = [input characterAtIndex:i];
        // Allow a leading '-' for negative integers
        if (!((c == '-' && i == 0) || (c >= '0' && c <= '9'))) {
            return NO;
        }
    }
    return YES;
}
mbm29414
  • 11,558
  • 6
  • 56
  • 87
2

Answer by @devsan is incorrect. If a user pastes anything with a a number such as "1abc" her code would break

It should be (allow replacement only if all the chars are digits):

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSCharacterSet *nonNumberSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
return ([string stringByTrimmingCharactersInSet:nonNumberSet].length == string.length) || [string isEqualToString:@""];
}
MD SHAHIDUL ISLAM
  • 14,325
  • 6
  • 82
  • 89
unify
  • 6,161
  • 4
  • 33
  • 34
1

Want to allow negative numbers as well?

Elaborating on davsan's answer, here is a solution that supports entering negative as well as positive numbers, and disallows anything else.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSCharacterSet *nonNumberSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
    return ([string stringByTrimmingCharactersInSet:nonNumberSet].length > 0) || [string isEqualToString:@""] || ([textField.text isEqualToString:@""] && [string isEqualToString:@"-"]);

    return YES;
}
DiscDev
  • 38,652
  • 20
  • 117
  • 133
1

You could also use UITextFieldDelegate method

textField:shouldChangeCharactersInRange:replacementString:

to live check that each time the user press a key, it is a simple digit, so that he/she knows that only int value is to be entered in the field.

dodecaplex
  • 1,119
  • 2
  • 8
  • 10
0

This code is work with localisation too .

  - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {
        if([string isEqualToString:@""]) return YES;
        NSCharacterSet *characterSet = nil;
        characterSet = [NSCharacterSet decimalDigitCharacterSet];
        NSRange location = [string rangeOfCharacterFromSet:characterSet];
        return (location.location != NSNotFound);

        if(characterSet == nil) return YES;
        return YES;

    }
Shreesh Garg
  • 562
  • 5
  • 18