Lutte avec NSNumberFormatter dans Swift pour la monnaie

Je crée une application de budget qui permet à l’utilisateur d’entrer son budget ainsi que les transactions. Je dois permettre à l’utilisateur de saisir à la fois des pences et des livres dans des champs de texte distincts et ils doivent être formatés avec des symboles monétaires. Cela fonctionne bien pour le moment, mais je voudrais le localiser car actuellement, il ne fonctionne qu’avec le GBP. J’ai eu du mal à convertir les exemples NSNumberFormatter d’Objectif C en Swift.

Mon premier problème est le fait que je dois définir les espaces réservés pour que les champs de saisie soient spécifiques à l’emplacement des utilisateurs. Par exemple. Livres et Pence, Dollars et Cents etc …

Le second problème est que les valeurs entrées dans chacun des champs de texte, tels que 10216 et 32, doivent être formatées et que le symbole de devise spécifique à l’emplacement de l’utilisateur doit être ajouté. Donc, cela deviendrait 10 216,32 £ ou 10 216,32 $ etc …

De plus, je dois utiliser le résultat du nombre mis en forme dans un calcul. Alors, comment puis-je faire cela sans rencontrer de problèmes sans rencontrer de problèmes avec le symbole monétaire?

Toute aide serait très appréciée.

Voici un exemple d’utilisation sur Swift 3. ( Edit : Fonctionne aussi dans 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.ssortingng(from: price) // "$123.44" formatter.locale = Locale(identifier: "es_CL") formatter.ssortingng(from: price) // $123" formatter.locale = Locale(identifier: "es_ES") formatter.ssortingng(from: price) // "123,44 €" 

Voici l’ancien exemple d’utilisation de Swift 2.

 let price = 123.436 let formatter = NSNumberFormatter() formatter.numberStyle = .CurrencyStyle // formatter.locale = NSLocale.currentLocale() // This is the default formatter.ssortingngFromNumber(price) // "$123.44" formatter.locale = NSLocale(localeIdentifier: "es_CL") formatter.ssortingngFromNumber(price) // $123" formatter.locale = NSLocale(localeIdentifier: "es_ES") formatter.ssortingngFromNumber(price) // "123,44 €" 

J’ai également implémenté la solution fournie par @ NiñoScript:

Extension

 // Create a ssortingng with currency formatting based on the device locale // extension Float { var asLocaleCurrency:Ssortingng { var formatter = NSNumberFormatter() formatter.numberStyle = .CurrencyStyle formatter.locale = NSLocale.currentLocale() return formatter.ssortingngFromNumber(self)! } } 

Usage:

 let amount = 100.07 let amountSsortingng = amount.asLocaleCurrency print(amount.asLocaleCurrency()) // prints: "$100.07" 

Swift 3

  extension Float { var asLocaleCurrency:Ssortingng { var formatter = NumberFormatter() formatter.numberStyle = .currency formatter.locale = Locale.current return formatter.ssortingng(from: self)! } } 

Swift 3:

Si vous recherchez une solution qui vous donne:

  • “5” = “$ 5”
  • “5.0” = “$ 5”
  • “5.00” = “$ 5”
  • “5.5” = “$ 5.50”
  • “5.50” = “$ 5.50”
  • “5,55” = “5,55 $”
  • “5.234234” = “5.23”

Veuillez utiliser ce qui suit:

 func cleanDollars(_ value: Ssortingng?) -> Ssortingng { 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.ssortingng(from: NSNumber(value: doubleValue)) ?? "$\(doubleValue)" } 

Xcode 9 • Swift 4

 extension Locale { static let br = Locale(identifier: "pt_BR") static let us = Locale(identifier: "en_US") static let uk = Locale(identifier: "en_UK") } 

 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 { // for Swift 3 use FloatingPoint or Int var currency: Ssortingng { return Formatter.currency.ssortingng(for: self) ?? "" } var currencyUS: Ssortingng { return Formatter.currencyUS.ssortingng(for: self) ?? "" } var currencyBR: Ssortingng { return Formatter.currencyBR.ssortingng(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" 

Détails

xCode 9.2, Swift 4

Solution 1

 import Foundation extension Ssortingng { var toLocale: Locale { return Locale(identifier: self) } } extension Numeric { func currency(numberStyle: NumberFormatter.Style = NumberFormatter.Style.currency, locale: Ssortingng, groupingSeparator: Ssortingng? = nil, decimalSeparator: Ssortingng? = nil) -> Ssortingng? { return currency(numberStyle: numberStyle, locale: locale.toLocale, groupingSeparator: groupingSeparator, decimalSeparator: decimalSeparator) } func currency(numberStyle: NumberFormatter.Style = NumberFormatter.Style.currency, locale: Locale = Locale.current, groupingSeparator: Ssortingng? = nil, decimalSeparator: Ssortingng? = nil) -> Ssortingng? { if let num = self as? NSNumber { let formater = NumberFormatter() formater.locale = locale formater.numberStyle = numberStyle var formatedSting = formater.ssortingng(from: num) if let separator = groupingSeparator, let localeValue = locale.groupingSeparator { formatedSting = formatedSting?.replacingOccurrences(of: localeValue, with: separator) } if let separator = decimalSeparator, let localeValue = locale.decimalSeparator { formatedSting = formatedSting?.replacingOccurrences(of: localeValue, with: separator) } return formatedSting } return nil } } 

Usage

 let price = 12423.42 print(price.currency() ?? "nil") print(price.currency(numberStyle: .currencyISOCode) ?? "nil") print(price.currency(locale: "es_ES") ?? "nil") print(price.currency(locale: "es_ES", groupingSeparator: "_", decimalSeparator: ".") ?? "nil") 

Résultat

entrer la description de l'image ici

Solution 2

 import Foundation extension Ssortingng { var toLocale: Locale { return Locale(identifier: self) } } class NumFormatter { static var shared = NumFormatter() public private(set) var formater = NumberFormatter() public private(set) var groupingSeparator: Ssortingng? = nil public private(set) var decimalSeparator: Ssortingng? = nil public var locale: Locale { return formater.locale } class func locale(ssortingng: Ssortingng) -> NumFormatter.Type { NumFormatter.shared.formater.locale = ssortingng.toLocale return NumFormatter.self } class func number(style: NumberFormatter.Style = NumberFormatter.Style.currency) -> NumFormatter.Type { NumFormatter.shared.formater.numberStyle = style return NumFormatter.self } class func number(groupingSeparator: Ssortingng?) -> NumFormatter.Type { NumFormatter.shared.groupingSeparator = groupingSeparator return NumFormatter.self } class func number(decimalSeparator: Ssortingng?) -> NumFormatter.Type { NumFormatter.shared.decimalSeparator = decimalSeparator return NumFormatter.self } } extension Numeric { func currency() -> Ssortingng? { if let num = self as? NSNumber { let formater = NumFormatter.shared.formater var formatedSting = formater.ssortingng(from: num) if let separator = NumFormatter.shared.groupingSeparator, let localeValue = formater.locale.groupingSeparator { formatedSting = formatedSting?.replacingOccurrences(of: localeValue, with: separator) } if let separator = NumFormatter.shared.decimalSeparator, let localeValue = formater.locale.decimalSeparator { formatedSting = formatedSting?.replacingOccurrences(of: localeValue, with: separator) } return formatedSting } return nil } } 

Usage

 let price = 12423.42 print(price.currency() ?? "nil") NumFormatter.number(style: .currencyISOCode) print(price.currency() ?? "nil") NumFormatter.locale(ssortingng: "es_ES") print(price.currency() ?? "nil") NumFormatter.number(groupingSeparator: "_").number(decimalSeparator: ".") print(price.currency() ?? "nil") 

Swift 4

 formatter.locale = Locale.current 

si vous voulez changer de langue, vous pouvez le faire comme ça

 formatter.locale = Locale.init(identifier: "id-ID") 

// Ceci est la locale pour les parameters régionaux de l’Indonésie. si vous souhaitez utiliser selon la zone de téléphonie mobile, utilisez-la selon la mention supérieure Locale.current

 //MARK:- Complete code let formatter = NumberFormatter() formatter.numberStyle = .currency if let formattedTipAmount = formatter.ssortingng(from: Int(newSsortingng)! as NSNumber) { yourtextfield.text = formattedTipAmount } 

append cette fonction

 func addSeparateMarkForNumber(int: Int) -> Ssortingng { var ssortingng = "" let formatter = NumberFormatter() formatter.locale = Locale.current formatter.numberStyle = .decimal if let formattedTipAmount = formatter.ssortingng(from: int as NSNumber) { ssortingng = formattedTipAmount } return ssortingng } 

en utilisant:

 let giaTri = value as! Int myGuessTotalCorrect = addSeparateMarkForNumber(int: giaTri) 
 extension Float { var convertAsLocaleCurrency :Ssortingng { var formatter = NumberFormatter() formatter.numberStyle = .currency formatter.locale = Locale.current return formatter.ssortingng(from: self as NSNumber)! } } 

Cela fonctionne pour swift 3.1 xcode 8.2.1