Я создаю бюджетное приложение, которое позволяет пользователю вводить свой бюджет, а также транзакции. Мне нужно разрешить пользователю вводить как пенсы, так и фунты из отдельных текстовых полей, и они должны быть отформатированы вместе с символами валюты. На данный момент у меня это работает нормально, но я бы хотел сделать его локализованным, поскольку в настоящее время он работает только с фунтами стерлингов. Я изо всех сил пытался скрыть примеры NSNumberFormatter от Objective C до Swift.
Моя первая проблема заключается в том, что мне нужно установить заполнители для полей ввода, специфичные для местоположения пользователя. Например. Фунты и пенсы, доллары и центы и т. Д.
Вторая проблема заключается в том, что значения, вводимые в каждое из текстовых полей, таких как 10216 и 32, должны быть отформатированы, и необходимо добавить символ валюты, специфичный для местоположения пользователя. Таким образом, получилось бы 10216,32 фунта стерлингов или 10216,32 доллара США и т. Д.
Кроме того, мне нужно использовать результат отформатированного числа в вычислении. Итак, как я могу сделать это, не столкнувшись с проблемами, не столкнувшись с проблемами с символом валюты?
Любая помощь приветствуется.
источник
Ответы:
Вот пример того, как использовать его в Swift 3. ( Edit : работает и в Swift 4)
let price = 123.436 as NSNumber let formatter = NumberFormatter() formatter.numberStyle = .currency // formatter.locale = NSLocale.currentLocale() // This is the default // In Swift 4, this ^ has been 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 €"
Вот старый пример того, как его использовать в 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 €"
источник
string(for: price)
вместоstring(from: price)
Swift 3:
Если вы ищете решение, которое даст вам:
Пожалуйста, используйте следующее:
func cleanDollars(_ value: String?) -> String { guard value != nil else { return "$0.00" } let doubleValue = Double(value!) ?? 0.0 let formatter = NumberFormatter() formatter.currencyCode = "USD" formatter.currencySymbol = "$" formatter.minimumFractionDigits = (value!.contains(".00")) ? 0 : 2 formatter.maximumFractionDigits = 2 formatter.numberStyle = .currencyAccounting return formatter.string(from: NSNumber(value: doubleValue)) ?? "$\(doubleValue)" }
источник
func string(for obj: Any?) -> String?
вместоstring(from:)
Я также реализовал решение, предоставленное @ NiñoScript, как расширение:
Расширение
// Create a string with currency formatting based on the device locale // extension Float { var asLocaleCurrency:String { var formatter = NSNumberFormatter() formatter.numberStyle = .CurrencyStyle formatter.locale = NSLocale.currentLocale() return formatter.stringFromNumber(self)! } }
Применение:
let amount = 100.07 let amountString = amount.asLocaleCurrency print(amount.asLocaleCurrency()) // prints: "$100.07"
Swift 3
extension Float { var asLocaleCurrency:String { var formatter = NumberFormatter() formatter.numberStyle = .currency formatter.locale = Locale.current return formatter.string(from: self)! } }
источник
Xcode 11 • Swift 5.1
extension Locale { static let br = Locale(identifier: "pt_BR") static let us = Locale(identifier: "en_US") static let uk = Locale(identifier: "en_GB") // ISO Locale }
extension NumberFormatter { convenience init(style: Style, locale: Locale = .current) { self.init() self.locale = locale numberStyle = style } }
extension Formatter { static let currency = NumberFormatter(style: .currency) static let currencyUS = NumberFormatter(style: .currency, locale: .us) static let currencyBR = NumberFormatter(style: .currency, locale: .br) }
extension Numeric { var currency: String { Formatter.currency.string(for: self) ?? "" } var currencyUS: String { Formatter.currencyUS.string(for: self) ?? "" } var currencyBR: String { Formatter.currencyBR.string(for: self) ?? "" } }
let price = 1.99 print(Formatter.currency.locale) // "en_US (current)\n" print(price.currency) // "$1.99\n" Formatter.currency.locale = .br print(price.currency) // "R$1,99\n" Formatter.currency.locale = .uk print(price.currency) // "£1.99\n" print(price.currencyBR) // "R$1,99\n" print(price.currencyUS) // "$1.99\n"
источник
Детали
Решение
import Foundation class CurrencyFormatter { static var outputFormatter = CurrencyFormatter.create() class func create(locale: Locale = Locale.current, groupingSeparator: String? = nil, decimalSeparator: String? = nil, style: NumberFormatter.Style = NumberFormatter.Style.currency) -> NumberFormatter { let outputFormatter = NumberFormatter() outputFormatter.locale = locale outputFormatter.decimalSeparator = decimalSeparator ?? locale.decimalSeparator outputFormatter.groupingSeparator = groupingSeparator ?? locale.groupingSeparator outputFormatter.numberStyle = style return outputFormatter } } extension Numeric { func toCurrency(formatter: NumberFormatter = CurrencyFormatter.outputFormatter) -> String? { guard let num = self as? NSNumber else { return nil } var formatedSting = formatter.string(from: num) guard let locale = formatter.locale else { return formatedSting } if let separator = formatter.groupingSeparator, let localeValue = locale.groupingSeparator { formatedSting = formatedSting?.replacingOccurrences(of: localeValue, with: separator) } if let separator = formatter.decimalSeparator, let localeValue = locale.decimalSeparator { formatedSting = formatedSting?.replacingOccurrences(of: localeValue, with: separator) } return formatedSting } }
Применение
let price = 12423.42 print(price.toCurrency() ?? "") CurrencyFormatter.outputFormatter = CurrencyFormatter.create(style: .currencyISOCode) print(price.toCurrency() ?? "nil") CurrencyFormatter.outputFormatter = CurrencyFormatter.create(locale: Locale(identifier: "es_ES")) print(price.toCurrency() ?? "nil") CurrencyFormatter.outputFormatter = CurrencyFormatter.create(locale: Locale(identifier: "de_DE"), groupingSeparator: " ", style: .currencyISOCode) print(price.toCurrency() ?? "nil") CurrencyFormatter.outputFormatter = CurrencyFormatter.create(groupingSeparator: "_", decimalSeparator: ".", style: .currencyPlural) print(price.toCurrency() ?? "nil") let formatter = CurrencyFormatter.create(locale: Locale(identifier: "de_DE"), groupingSeparator: " ", decimalSeparator: ",", style: .currencyPlural) print(price.toCurrency(formatter: formatter) ?? "nil")
Полученные результаты
$12,423.42 USD12,423.42 12.423,42 € 12 423,42 EUR 12_423.42 US dollars 12 423,42 Euro
источник
Обновлено для Swift 4 из ответа @Michael Voccola:
extension Double { var asLocaleCurrency: String { let formatter = NumberFormatter() formatter.numberStyle = .currency formatter.locale = Locale.current let formattedString = formatter.string(from: self as NSNumber) return formattedString ?? "" } }
Примечание: принудительное развертывание запрещено, принудительное развертывание - зло.
источник
Реализовано текстовое поле Swift 4
var value = 0 currencyTextField.delegate = self func numberFormatting(money: Int) -> String { let formatter = NumberFormatter() formatter.numberStyle = .currency formatter.locale = .current return formatter.string(from: money as NSNumber)! } currencyTextField.text = formatter.string(from: 50 as NSNumber)! func textFieldDidEndEditing(_ textField: UITextField) { value = textField.text textField.text = numberFormatting(money: Int(textField.text!) ?? 0 as! Int) } func textFieldDidBeginEditing(_ textField: UITextField) { textField.text = value }
источник
extension Float { var convertAsLocaleCurrency :String { var formatter = NumberFormatter() formatter.numberStyle = .currency formatter.locale = Locale.current return formatter.string(from: self as NSNumber)! } }
Это работает для swift 3.1 xcode 8.2.1
источник
Swift 4
formatter.locale = Locale.current
если вы хотите изменить язык, вы можете сделать это так
formatter.locale = Locale.init(identifier: "id-ID")
// Это локаль для локали Индонезии. если вы хотите использовать в соответствии с областью мобильного телефона, используйте его в соответствии с верхним упоминанием Locale.current
//MARK:- Complete code let formatter = NumberFormatter() formatter.numberStyle = .currency if let formattedTipAmount = formatter.string(from: Int(newString)! as NSNumber) { yourtextfield.text = formattedTipAmount }
источник
добавить эту функцию
func addSeparateMarkForNumber(int: Int) -> String { var string = "" let formatter = NumberFormatter() formatter.locale = Locale.current formatter.numberStyle = .decimal if let formattedTipAmount = formatter.string(from: int as NSNumber) { string = formattedTipAmount } return string }
с помощью:
let giaTri = value as! Int myGuessTotalCorrect = addSeparateMarkForNumber(int: giaTri)
источник