Skip to main content

iPhone how to check that a string is numeric only



How do I validate the string input from a UITextField? I want to check that the string is numeric, including decimal points.




Comments

  1. I use this code in my Mac app, the same or similar should work with the iPhone. It's based on the RegexKitLite regular expressions and turns the text red when its invalid.

    static bool TextIsValidValue( NSString* newText, double &value )
    {
    bool result = false;

    if ( [newText isMatchedByRegex:@"^(?:|0|[1-9]\\d*)(?:\\.\\d*)?$"] ) {
    result = true;
    value = [newText doubleValue];
    }
    return result;
    }

    - (IBAction) doTextChanged:(id)sender;
    {
    double value;
    if ( TextIsValidValue( [i_pause stringValue], value ) ) {
    [i_pause setTextColor:[NSColor blackColor]];
    // do something with the value
    } else {
    [i_pause setTextColor:[NSColor redColor]];
    }
    }

    ReplyDelete
  2. There are a few ways you could do this:


    Use NSNumberFormatter's numberFromString: method. This will return an NSNumber if it can parse the string correctly, or nil if it cannot.
    Use NSScanner
    Strip any non-numeric character and see if the string still matches
    Use a regular expression


    IMO, using something like -[NSString doubleValue] wouldn't be the best option because both @"0.0" and @"abc" will have a doubleValue of 0. The *value methods all return 0 if they're not able to convert the string properly, so it would be difficult to distinguish between a legitimate string of @"0" and a non-valid string. Something like C's strtol function would have the same issue.

    I think using NSNumberFormatter would be the best option, since it takes locale into account (ie, the number @"1,23" in Europe, versus @"1.23" in the USA).

    ReplyDelete
  3. You can do it in a few lines like this:

    BOOL valid;

    NSCharacterSet *alphaNums = [NSCharacterSet decimalDigitCharacterSet];

    NSCharacterSet *inStringSet = [NSCharacterSet characterSetWithCharactersInString:myInputField.text];

    valid = [alphaNums isSupersetOfSet:inStringSet];

    if (!valid) //


    -- this is for validating input is numeric chars only. Look at the documentation for NSCharacterSet for the other options. You can use characterSetWithCharactersInString to specify any set of valid input characters.

    ReplyDelete
  4. If you want a user to only be allowed to enter numerals, you can make your ViewController implement part of UITextFieldDelegate and define this method:

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSString *resultingString = [textField.text stringByReplacingCharactersInRange: range withString: string];

    // The user deleting all input is perfectly acceptable.
    if ([resultingString length] == 0) {
    return true;
    }

    NSInteger holder;

    NSScanner *scan = [NSScanner scannerWithString: resultingString];

    return [scan scanInteger: &holder] && [scan isAtEnd];
    }


    There are probably more efficient ways, but I find this a pretty convenient way. And the method should be readily adaptable to validating doubles or whatever: just use scanDouble: or similar.

    ReplyDelete
  5. #pragma mark - UItextfield Delegate

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    if ([string isEqualToString:@"("]||[string isEqualToString:@")"]) {
    return TRUE;
    }

    NSLog(@"Range ==%d ,%d",range.length,range.location);
    //NSRange *CURRANGE = [NSString rangeOfString:string];

    if (range.location == 0 && range.length == 0) {
    if ([string isEqualToString:@"+"]) {
    return TRUE;
    }
    }
    return [self isNumeric:string];
    }

    -(BOOL)isNumeric:(NSString*)inputString{
    BOOL isValid = NO;
    NSCharacterSet *alphaNumbersSet = [NSCharacterSet decimalDigitCharacterSet];
    NSCharacterSet *stringSet = [NSCharacterSet characterSetWithCharactersInString:inputString];
    isValid = [alphaNumbersSet isSupersetOfSet:stringSet];
    return isValid;
    }

    ReplyDelete
  6. You can use the doubleValue of your string like

    NSString *string=@"1.22";
    double a=[string doubleValue];


    i think this will return a as 0.0 if the string is invalid (it might throw an exception, in which case you can just catch it, the docs say 0.0 tho). more info here http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSString%5FClass/Reference/NSString.html#//apple%5Fref/occ/instm/NSString/doubleValue

    ReplyDelete
  7. I wanted a text field that only allowed integers. Here's what I ended up with (using info from here and elsewhere):

    Create integer number formatter (in UIApplicationDelegate so it can be reused):

    @property (nonatomic, retain) NSNumberFormatter *integerNumberFormatter;

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    // Create and configure an NSNumberFormatter for integers
    integerNumberFormatter = [[NSNumberFormatter alloc] init];
    [integerNumberFormatter setMaximumFractionDigits:0];

    return YES;
    }


    Use filter in UITextFieldDelegate:

    @interface MyTableViewController : UITableViewController <UITextFieldDelegate> {
    ictAppDelegate *appDelegate;
    }

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    // Make sure the proposed string is a number
    NSNumberFormatter *inf = [appDelegate integerNumberFormatter];
    NSString* proposedString = [textField.text stringByReplacingCharactersInRange:range withString:string];
    NSNumber *proposedNumber = [inf numberFromString:proposedString];
    if (proposedNumber) {
    // Make sure the proposed number is an integer
    NSString *integerString = [inf stringFromNumber:proposedNumber];
    if ([integerString isEqualToString:proposedString]) {
    // proposed string is an integer
    return YES;
    }
    }

    // Warn the user we're rejecting the change
    AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
    return NO;
    }

    ReplyDelete
  8. @property (strong) NSNumberFormatter *numberFormatter;
    @property (strong) NSString *oldStringValue;

    - (void)awakeFromNib
    {
    [super awakeFromNib];
    self.numberFormatter = [[NSNumberFormatter alloc] init];
    self.oldStringValue = self.stringValue;
    [self setDelegate:self];
    }

    - (void)controlTextDidChange:(NSNotification *)obj
    {
    NSNumber *number = [self.numberFormatter numberFromString:self.stringValue];
    if (number) {
    self.oldStringValue = self.stringValue;
    } else {
    self.stringValue = self.oldStringValue;
    }
    }

    ReplyDelete

Post a Comment

Popular posts from this blog

[韓日関係] 首相含む大幅な内閣改造の可能性…早ければ来月10日ごろ=韓国

div not scrolling properly with slimScroll plugin

I am using the slimScroll plugin for jQuery by Piotr Rochala Which is a great plugin for nice scrollbars on most browsers but I am stuck because I am using it for a chat box and whenever the user appends new text to the boxit does scroll using the .scrollTop() method however the plugin's scrollbar doesnt scroll with it and when the user wants to look though the chat history it will start scrolling from near the top. I have made a quick demo of my situation http://jsfiddle.net/DY9CT/2/ Does anyone know how to solve this problem?

Why does this javascript based printing cause Safari to refresh the page?

The page I am working on has a javascript function executed to print parts of the page. For some reason, printing in Safari, causes the window to somehow update. I say somehow, because it does not really refresh as in reload the page, but rather it starts the "rendering" of the page from start, i.e. scroll to top, flash animations start from 0, and so forth. The effect is reproduced by this fiddle: http://jsfiddle.net/fYmnB/ Clicking the print button and finishing or cancelling a print in Safari causes the screen to "go white" for a sec, which in my real website manifests itself as something "like" a reload. While running print button with, let's say, Firefox, just opens and closes the print dialogue without affecting the fiddle page in any way. Is there something with my way of calling the browsers print method that causes this, or how can it be explained - and preferably, avoided? P.S.: On my real site the same occurs with Chrome. In the ex