Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restrict NSTextField input to numeric only? NSNumberformatter

I'm just getting started up with Mac App Development and so far everything is good well, I'm just having problems trying to get a NSTextField to only accept numbers for the input.

So far I have added a formatter to the NSTextField and set it to only allow decimal now when I enter letters in the field it still allows me but does not allow my to click out of the cell when done.

Ideally I would like the app not to let the user type in any letters and just beep or do nothing.

Any tips or pointers on this would be great

like image 745
MonkeyBlue Avatar asked Jan 10 '11 23:01

MonkeyBlue


2 Answers

Here are the steps to create the same:

Just create the ANYCLASS (called SAMPLE) subclassing the NSNumberFormatter, and in the .m file write the following code...

-(BOOL)isPartialStringValid:(NSString *)partialString newEditingString:(NSString **)newString errorDescription:(NSString **) error {
    // Make sure we clear newString and error to ensure old values aren't being used
    if (newString) { *newString = nil;}
    if (error)     {*error = nil;}

    static NSCharacterSet *nonDecimalCharacters = nil;
    if (nonDecimalCharacters == nil) {
        nonDecimalCharacters = [[NSCharacterSet decimalDigitCharacterSet] invertedSet] ;
    }

    if ([partialString length] == 0) {
        return YES; // The empty string is okay (the user might just be deleting everything and starting over)
    } else if ([partialString rangeOfCharacterFromSet:nonDecimalCharacters].location != NSNotFound) {
        return NO; // Non-decimal characters aren't cool!
    }

    return YES;
}

Now in your Actual Class set the formatter to your NSTextField object like this:

NSTextField *mySampleTxtFld;

And for this set the Formatter:

SAMPLE* formatter=[[SAMPLE alloc]init]; // create SAMPLE FORMATTER OBJECT 

self.mySampleTxtFld.delegate=self;
[self.mySampleTxtFld setFormatter:formatter];

You’re done!

like image 169
VSN Avatar answered Oct 04 '22 09:10

VSN


Rather than subclassing anything, you can do it with an NSControlTextEditingDelegate method in your view controller. Set the delegate field of the NSTextField you want to check and then do something like the following in a controlTextDidChange: function which gets called on each character typed. Don't forget to initialize self.lastValidTimestampCount in this case. This function uses RegExLite to check the value, which may include commas.

// Make sure the user has typed a valid number so far.
- (void)controlTextDidChange:(NSNotification *)obj
{
    if (obj.object == self.timestampsCount)
    {
        NSString *countValue = timestampsCount.stringValue;
        if (! [countValue isMatchedByRegex:@"^[\\d\\,]{1,6}$"])
        {
            timestampsCount.stringValue = self.lastValidTimestampCount;
            NSBeep();
        }
        else
            self.lastValidTimestampCount = timestampsCount.stringValue;
    }
}
like image 39
NPAssoc Avatar answered Oct 04 '22 09:10

NPAssoc