Formatting UITextField input as currency
In both of my apps, the user may input a price or cost text field. I want this to look good no matter the user’s locale.
This snippet does the following:
– adds the localized currency symbol if necessary.
– if user inputs only dollar amount, append zero cents with the appropriate decimal separator.
i.e. with US_EN locale, change
42 -> $42.00
$42 -> $42.00
42.4 -> $42.40
42.00 -> $42.00
$42.00 -> $42.00 (no change, no crash)
The one case it won’t handle is:
$42.4 does not produce $42.40
Russian:
42 -> 42,00 руб.
etc.
Germany:
42 -> 42,00 €
etc.
Note that if you will need to do any calculations with the number, you will obviously need to save it off before you modify the corresponding text string.
Example:
– (void)textFieldDidEndEditing:(UITextField *)textField
{
if( aPriceField == textField )
{
// if needed, save unmodified text string as decimal number here
[self formatCurrencyField:textField];
}
}
code:
– (void)formatCurrencyField:(UITextField *)textField
{
NSLocale* currentUserLocale = [NSLocale currentLocale];
// If the user just typed the number in, e.g. 12.34 or 42, prepend the currency symbol:
NSString *currencySymbol = [currentUserLocale objectForKey:NSLocaleCurrencySymbol];
NSRange strRange = [textField.text rangeOfString:currencySymbol];
if (strRange.location == NSNotFound)
{
NSString *numberStr = [NSNumberFormatter localizedStringFromNumber:[NSDecimalNumber numberWithFloat:[textField.text floatValue]]
numberStyle:NSNumberFormatterCurrencyStyle];
textField.text = numberStr;
}
else
{
// contains a currency symbol, but we don’t know if it’s in the form $xx.nn or just $xx.
// If it’s $xx, we want to change it to $xx.00:
NSString *decimalSeparator = [currentUserLocale objectForKey:NSLocaleDecimalSeparator];
NSRange resultsRange = [textField.text rangeOfString:decimalSeparator
options:NSCaseInsensitiveSearch];
if(resultsRange.location == NSNotFound)
{
// number is in form $XX, change it to $XX.00:
NSNumberFormatter *costFmt = [[NSNumberFormatter alloc] init];
[costFmt setNumberStyle:NSNumberFormatterCurrencyStyle];
NSNumber* floatNum = [costFmt numberFromString:textField.text];
NSNumber *costNum=[NSNumber numberWithFloat:[floatNum floatValue]];
NSString* costStr = [costFmt stringFromNumber:costNum];
textField.text = costStr;
}
}
}
{
NSLocale* currentUserLocale = [NSLocale currentLocale];
// If the user just typed the number in, e.g. 12.34 or 42, prepend the currency symbol:
NSString *currencySymbol = [currentUserLocale objectForKey:NSLocaleCurrencySymbol];
NSRange strRange = [textField.text rangeOfString:currencySymbol];
if (strRange.location == NSNotFound)
{
NSString *numberStr = [NSNumberFormatter localizedStringFromNumber:[NSDecimalNumber numberWithFloat:[textField.text floatValue]]
numberStyle:NSNumberFormatterCurrencyStyle];
textField.text = numberStr;
}
else
{
// contains a currency symbol, but we don’t know if it’s in the form $xx.nn or just $xx.
// If it’s $xx, we want to change it to $xx.00:
NSString *decimalSeparator = [currentUserLocale objectForKey:NSLocaleDecimalSeparator];
NSRange resultsRange = [textField.text rangeOfString:decimalSeparator
options:NSCaseInsensitiveSearch];
if(resultsRange.location == NSNotFound)
{
// number is in form $XX, change it to $XX.00:
NSNumberFormatter *costFmt = [[NSNumberFormatter alloc] init];
[costFmt setNumberStyle:NSNumberFormatterCurrencyStyle];
NSNumber* floatNum = [costFmt numberFromString:textField.text];
NSNumber *costNum=[NSNumber numberWithFloat:[floatNum floatValue]];
NSString* costStr = [costFmt stringFromNumber:costNum];
textField.text = costStr;
}
}
}