Formatting Input For Currency With Nsnumberformatter in Swift

Formatting input for currency with NSNumberFormatter in Swift

Here's an example on how to use it on Swift 3.
( Edit: Works in Swift 5 too )

let price = 123.436 as NSNumber

let formatter = NumberFormatter()
formatter.numberStyle = .currency
// formatter.locale = NSLocale.currentLocale() // This is the default
// In Swift 4, this ^ was renamed to simply NSLocale.current
formatter.string(from: price) // "$123.44"

formatter.locale = Locale(identifier: "es_CL")
formatter.string(from: price) // $123"

formatter.locale = Locale(identifier: "es_ES")
formatter.string(from: price) // "123,44 €"

Here's the old example on how to use it on Swift 2.

let price = 123.436

let formatter = NSNumberFormatter()
formatter.numberStyle = .CurrencyStyle
// formatter.locale = NSLocale.currentLocale() // This is the default
formatter.stringFromNumber(price) // "$123.44"

formatter.locale = NSLocale(localeIdentifier: "es_CL")
formatter.stringFromNumber(price) // $123"

formatter.locale = NSLocale(localeIdentifier: "es_ES")
formatter.stringFromNumber(price) // "123,44 €"

NSNumberFormatter.number for currency format not working in Device but works in simulator

The decimal separator is locale-dependent, therefore parsing "1234.45"
fails if the locale's separator is not a period.

It the input string uses a fixed format with a period as decimal separator
then you can set the formatter's locale to "en_US_POSIX" for the conversion
from a string to a number. Then set it to the desired locale for the conversion
from number to a string.

Example:

func currencyFormatter(language: String, amount: String)  -> String  {

let nsFormatter = NumberFormatter()
nsFormatter.locale = Locale(identifier: "en_US_POSIX")
nsFormatter.numberStyle = .decimal

guard let number = nsFormatter.number(from: amount) else {
return amount
}

nsFormatter.locale = Locale(identifier: language)
nsFormatter.numberStyle = .currency

return nsFormatter.string(from: number) ?? amount
}

print(currencyFormatter(language: "fr-FR", amount: "1234.45"))
// 1 234,45 €

How to input currency format on a text field (from right to left) using Swift?

For Swift 3. Input currency format on a text field (from right to left)

override func viewDidLoad() {
super.viewDidLoad()

textField.addTarget(self, action: #selector(myTextFieldDidChange), for: .editingChanged)
}

@objc func myTextFieldDidChange(_ textField: UITextField) {

if let amountString = textField.text?.currencyInputFormatting() {
textField.text = amountString
}
}

extension String {

// formatting text for currency textField
func currencyInputFormatting() -> String {

var number: NSNumber!
let formatter = NumberFormatter()
formatter.numberStyle = .currencyAccounting
formatter.currencySymbol = "$"
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2

var amountWithPrefix = self

// remove from String: "$", ".", ","
let regex = try! NSRegularExpression(pattern: "[^0-9]", options: .caseInsensitive)
amountWithPrefix = regex.stringByReplacingMatches(in: amountWithPrefix, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, self.count), withTemplate: "")

let double = (amountWithPrefix as NSString).doubleValue
number = NSNumber(value: (double / 100))

// if first number is 0 or all numbers were deleted
guard number != 0 as NSNumber else {
return ""
}

return formatter.string(from: number)!
}
}

custom number formatter with currency symbol

For the static solution you can simply change format from .#.## to .#.## €

If you're looking for universal way to do it, you're interested with symbol ¤, which is responsible for currency sign.

So the format which are you looking for is ,#.## ¤

Last step is to check option lenient, otherwise you need to provide full format in text field.

More details

Since OSX 10.9 and iOS 7 the format strings uses patterns from the Unicode Technical Standard #35 of version 31.

You can find all number format patterns in this version here

Apple documentation about number formatters

NSNumberFormatter - get currency symbol for currency code

You're forcing currencyCode to 'GPD' but other properties of currency style as symbol, internationalCurrencySymbol, ... They depend on Locale. Check this:

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.usesGroupingSeparator = YES;
formatter.numberStyle = NSNumberFormatterCurrencyStyle;
formatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_UK"];

NSLog(@"%@", [formatter stringFromNumber:[NSNumber numberWithDouble:123456]]);
NSLog(@"%@", formatter.currencySymbol);
NSLog(@"%@", formatter.currencyCode);
NSLog(@"%@", formatter.internationalCurrencySymbol);

It will print:

£123,456.00
£
GBP
GBP

Then edit only the currency code to USD as the way you did:

US$123,456.00
£
USD
GBP

NSNumberFormatter currency: plusSign replaces currency

Turns out accounting is your rescue, change the number style

numberStyle = .currencyAccounting

and you get your expected output

How to format a Double into Currency - Swift 3

You can use this string initializer if you want to force the currency to $:

String(format: "Tip Amount: $%.02f", tipAmount)

If you want it to be fully dependent on the locale settings of the device, you should use a NumberFormatter. This will take into account the number of decimal places for the currency as well as positioning the currency symbol correctly. E.g. the double value 2.4 will return "2,40 €" for the es_ES locale and "¥ 2" for the jp_JP locale.

let formatter = NumberFormatter()
formatter.locale = Locale.current // Change this to another locale if you want to force a specific locale, otherwise this is redundant as the current locale is the default already
formatter.numberStyle = .currency
if let formattedTipAmount = formatter.string(from: tipAmount as NSNumber) {
tipAmountLabel.text = "Tip Amount: \(formattedTipAmount)"
}


Related Topics



Leave a reply



Submit