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

Why is this Javascript much *slower* than its jQuery equivalent?

I have a HTML list of about 500 items and a "filter" box above it. I started by using jQuery to filter the list when I typed a letter (timing code added later): $('#filter').keyup( function() { var jqStart = (new Date).getTime(); var search = $(this).val().toLowerCase(); var $list = $('ul.ablist > li'); $list.each( function() { if ( $(this).text().toLowerCase().indexOf(search) === -1 ) $(this).hide(); else $(this).show(); } ); console.log('Time: ' + ((new Date).getTime() - jqStart)); } ); However, there was a couple of seconds delay after typing each letter (particularly the first letter). So I thought it may be slightly quicker if I used plain Javascript (I read recently that jQuery's each function is particularly slow). Here's my JS equivalent: document.getElementById('filter').addEventListener( 'keyup', function () { var jsStart = (new Date).getTime()...

Is it possible to have IF statement in an Echo statement in PHP

Thanks in advance. I did look at the other questions/answers that were similar and didn't find exactly what I was looking for. I'm trying to do this, am I on the right path? echo " <div id='tabs-".$match."'> <textarea id='".$match."' name='".$match."'>". if ($COLUMN_NAME === $match) { echo $FIELD_WITH_COLUMN_NAME; } else { } ."</textarea> <script type='text/javascript'> CKEDITOR.replace( '".$match."' ); </script> </div>"; I am getting the following error message in the browser: Parse error: syntax error, unexpected T_IF Please let me know if this is the right way to go about nesting an IF statement inside an echo. Thank you.