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
Read and Write a String from Text File
How to Set Cell Spacing and Uicollectionview - Uicollectionviewflowlayout Size Ratio
How to Round a Double to the Nearest Int in Swift
When Should I Access Properties With Self in Swift
Decrement Index in a Loop After Swift C-Style Loops Deprecated
Passing Lists from One Function to Another in Swift
Swift Compiler Segmentation Fault When Building
How to Import a Swift File from Another Swift File
Firestore: How to Get Random Documents in a Collection
Alamofire Get API Request Not Working as Expected
Formatting Input For Currency With Nsnumberformatter in Swift
All Dates Between Two Date Objects (Swift)
Saving Picked Image to Coredata