views:

418

answers:

4

I noticed that the iPhone OS is pretty good about picking out Integer values when asked to. Specifically, if you use

NSString *stringName = @"6(";
int number = [stringName intValue];

the iPhone OS will pick out the 6 and turn the variable number into 6. However, in more complex mistypes, this also makes the int variable 6:

NSString *stringName = @"6(5";
int number = [stringName intValue];

The iPhone OS misses the other digit, when what could have possibly been the user trying to enter the number 65, the OS only gets the number 6 out of it. I need a solution to check a string for invalid characters and return NO if there is anything other than an unsigned integer in a textbox. This is for iPad, and currently there is no numeric keyboard like the iPhone has, and I'm instead limited to the standard 123 keyboard.

I was thinking that I need to use NSRange and somehow loop through the entire string in the textbox, and checking to see if the current character in the iteration is a number. I'm lost as far as that goes. I can think of testing it against zero, but zero is a valid integer.

Can anyone help?

A: 

I'd just have the UITextField's delegate veto any attempt to insert non-numeric characters. See -textField:shouldChangeCharactersInRange:replacementString:

NSResponder
+1  A: 

You probably want to use an NSScanner

With the NSScanner, you could do -scanInt:, then check -isAtEnd

David Gelhar
This is a great idea.
Jann
+2  A: 

Implement the UITextFieldDelegate method NSResponder mentioned, and check the replacement string with the NSString method -rangeOfCharacterFromSet:, like this:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)newString
{
    // create a character set containing everything except the decimal digits
    // (you might want to cache this, as inverting the set probably isn't fast)
    NSCharacterSet *nonNumericCharacters = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
    // and check whether there's a character in the string that's not in that set
    if([newString rangeOfCharacterFromSet:nonNumericCharacters].location != NSNotFound)
        return NO;
    return YES;
}
Noah Witherspoon
Or, better yet, tell a number formatter to attempt to parse the string. That will handle negative numbers, decimal points, and locale changes (e.g., different decimal points).
Peter Hosey
This may lead to a problem when user presses backspace.
Madhup
A: 
    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {

            if([string isEqualToString:@"\b"] || [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"] || [string isEqualToString:@"."])
            {
                return YES;
            }
           else{
                return NO;
           }
}

Hope this helps.

Thanks,

Madhup

Madhup
I don't think it's necessary to check for the backspace character—it isn't entered as such, you just get an empty string which replaces whatever character is just before the caret.
Noah Witherspoon