First, I setup up the keyboard for the UITextField to use the number with decimal style. So the user can only enter numbers and a single decimal.
What I want to do i
After much experimentation and looking at other's solutions (which seem to be overly complex and fiddly) I came up with the following, which prevents the user from entering anything but a valid currency amount. Basically, let an instance of NSNumberFormatter (created elsewhere in the viewController) do the hard work:
Firstly, I set the keyboard to UIKeyboardTypeDecimalPad. Then I used the following code
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
NSString *textString = [textField.text stringByReplacingCharactersInRange:range withString:string];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *amountNumber = [numberFormatter numberFromString:textString];
if ([textString length] > 0) {
if (!amountNumber) {
return NO;
}
} else {
amountNumber = @0;
}
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
NSString *amountStringer = [numberFormatter stringFromNumber:amountNumber];
NSNumber *amountAgain = [numberFormatter numberFromString:amountStringer];
//
//make sure that the number obtained again is the same....prevents too many decimals....
if (![amountNumber isEqualToNumber:amountAgain]) {
return NO;
}
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
amountShow.text = amountStringer;
self.amount = [NSDecimalNumber decimalNumberWithDecimal:[amountAgain decimalValue]];
NSLog(@"decimal Amount is %@", self.amount);
return YES;
}