I\'m working with a UITextField that holds a localized currency value. I\'ve seen lots of posts on how to work with this, but my question is: how do I re-apply currency for
This answer builds a little on Michael Klosson's code to fix some regional currency bugs, some locations caused his code to always spit out a 0 value in the final conversion back to textField string. I've also broke down the newText assignment to make it easier for some of us newer coders to digest, the nesting is tiresome for me sometimes. I logged out all NSLocale location options and their maximumFractionDigits value when an NSNUmberFormatter is set to them. I've found there were only 3 possibilities. Most use 2, some others use none, and a few use 3. This textfield delegate method handles all 3 possibilities, to ensure proper format based on region.
Here is my textField delegate method, mainly just a rewrite of Michael's code, but with the newText assignment expanded out, regional decimal support added, and using NSDecimalNumbers as thats what I'm storing in my core data model anyway.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// get the format symbols
NSNumberFormatter *currencyFormatter = self.currencyFormatter;
NSString *currencySymbol = currencyFormatter.currencySymbol;
NSString *groupSeperator = currencyFormatter.groupingSeparator;
NSString *decimalSeperator = currencyFormatter.decimalSeparator;
// strip all the format symbols to leave an integer representation
NSString* newText = [textField.text stringByReplacingCharactersInRange:range withString:string];
newText = [newText stringByReplacingOccurrencesOfString:currencySymbol withString:@""];
newText = [newText stringByReplacingOccurrencesOfString:groupSeperator withString:@""];
newText = [newText stringByReplacingOccurrencesOfString:decimalSeperator withString:@""];
NSDecimalNumber *newValue = [NSDecimalNumber decimalNumberWithString:newText];
if ([newText length] == 0 || newValue == 0)
textField.text = nil;
else if ([newText length] > currencyFormatter.maximumSignificantDigits) {
// NSLog(@"We've maxed out the digits");
textField.text = textField.text;
} else {
// update to new value
NSDecimalNumber *divisor;
// we'll need a number to divide by if local currency uses fractions
switch (currencyFormatter.maximumFractionDigits) {
// the max fraction digits tells us the number of decimal places
// divide accordingly based on the 3 available options
case 0:
// NSLog(@"No Decimals");
divisor = [NSDecimalNumber decimalNumberWithString:@"1.0"];
break;
case 2:
// NSLog(@"2 Decimals");
divisor = [NSDecimalNumber decimalNumberWithString:@"100.0"];
break;
case 3:
// NSLog(@"3 Decimals");
divisor = [NSDecimalNumber decimalNumberWithString:@"1000.0"];
break;
default:
break;
}
NSDecimalNumber *newAmount = [newValue decimalNumberByDividingBy:divisor];
textField.text = [currencyFormatter stringFromNumber:newAmount];
}
return NO;
}