I am fairly new to Swift and having a great deal of trouble finding a way to add a space as a thousand separator.
What I am hoping to achieve is taking the result of a calculation and displaying it in a textfield so that the format is:
2 358 000
instead of
2358000
for example.
I am not sure if I should be formatting the Int value and then converting it to a String, or adding the space after the Int value is converted to a String. Any help would be greatly appreciated.
The character used as the thousands separatorIn the United States, this character is a comma (,). In Germany, it is a period (.). Thus one thousand and twenty-five is displayed as 1,025 in the United States and 1.025 in Germany. In Sweden, the thousands separator is a space.
You can use NSNumberFormatter to specify a different grouping separator as follow:
update: Xcode 11.5 • Swift 5.2
extension Formatter { static let withSeparator: NumberFormatter = { let formatter = NumberFormatter() formatter.numberStyle = .decimal formatter.groupingSeparator = " " return formatter }() }
extension Numeric { var formattedWithSeparator: String { Formatter.withSeparator.string(for: self) ?? "" } }
2358000.formattedWithSeparator // "2 358 000" 2358000.99.formattedWithSeparator // "2 358 000.99" let int = 2358000 let intFormatted = int.formattedWithSeparator // "2 358 000" let decimal: Decimal = 2358000 let decimalFormatted = decimal.formattedWithSeparator // "2 358 000" let decimalWithFractionalDigits: Decimal = 2358000.99 let decimalWithFractionalDigitsFormatted = decimalWithFractionalDigits.formattedWithSeparator // "2 358 000.99"
If you need to display your value as currency with current locale or with a fixed locale:
extension Formatter { static let number = NumberFormatter() } extension Locale { static let englishUS: Locale = .init(identifier: "en_US") static let frenchFR: Locale = .init(identifier: "fr_FR") static let portugueseBR: Locale = .init(identifier: "pt_BR") // ... and so on } extension Numeric { func formatted(with groupingSeparator: String? = nil, style: NumberFormatter.Style, locale: Locale = .current) -> String { Formatter.number.locale = locale Formatter.number.numberStyle = style if let groupingSeparator = groupingSeparator { Formatter.number.groupingSeparator = groupingSeparator } return Formatter.number.string(for: self) ?? "" } // Localized var currency: String { formatted(style: .currency) } // Fixed locales var currencyUS: String { formatted(style: .currency, locale: .englishUS) } var currencyFR: String { formatted(style: .currency, locale: .frenchFR) } var currencyBR: String { formatted(style: .currency, locale: .portugueseBR) } // ... and so on var calculator: String { formatted(groupingSeparator: " ", style: .decimal) } }
Usage:
1234.99.currency // "$1,234.99" 1234.99.currencyUS // "$1,234.99" 1234.99.currencyFR // "1 234,99 €" 1234.99.currencyBR // "R$ 1.234,99" 1234.99.calculator // "1 234.99"
Note: If you would like to have a space with the same width of a period you can use "\u{2008}"
unicode spaces
formatter.groupingSeparator = "\u{2008}"
You want to use NSNumberFormatter
:
let fmt = NSNumberFormatter() fmt.numberStyle = .DecimalStyle fmt.stringFromNumber(2358000) // with my locale, "2,358,000" fmt.locale = NSLocale(localeIdentifier: "fr_FR") fmt.stringFromNumber(2358000) // "2 358 000"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With