Je crée une application de budget qui permet à l'utilisateur de saisir son budget ainsi que ses transactions. Je dois autoriser l'utilisateur à saisir à la fois les pence et les livres dans des champs de texte séparés et ils doivent être formatés avec des symboles monétaires. Cela fonctionne bien pour le moment, mais je voudrais le rendre localisé car actuellement, il ne fonctionne qu'avec GBP. J'ai eu du mal à dissimuler des exemples NSNumberFormatter de l'Objectif C à 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 deuxième problème est que les valeurs entrées dans chacun des champs de texte tels que 10216 et 32 doivent être formatées et le symbole monétaire spécifique à l'emplacement des utilisateurs doit être ajouté. Cela deviendrait donc 10216,32 £ ou 10216,32 $ etc ...
De plus, je dois utiliser le résultat du nombre formaté 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.
la source
Réponses:
Voici un exemple sur la façon de l'utiliser sur Swift 3. ( Edit : fonctionne également 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.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 €"
Voici l'ancien exemple sur la façon de l'utiliser sur 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 €"
la source
string(for: price)
place destring(from: price)
Swift 3:
Si vous recherchez une solution qui vous donne:
Veuillez utiliser ce qui suit:
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)" }
la source
func string(for obj: Any?) -> String?
place destring(from:)
J'ai également implémenté la solution fournie par @ NiñoScript en tant qu'extension:
Extension
// 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)! } }
Usage:
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)! } }
la source
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"
la source
Détails
Solution
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 } }
Usage
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")
Résultats
$12,423.42 USD12,423.42 12.423,42 € 12 423,42 EUR 12_423.42 US dollars 12 423,42 Euro
la source
Mise à jour pour Swift 4 à partir de la réponse de @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 ?? "" } }
Remarque: pas de déballage forcé, le déballage forcé est maléfique.
la source
Swift 4 TextField mis en œuvre
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 }
la source
extension Float { var convertAsLocaleCurrency :String { var formatter = NumberFormatter() formatter.numberStyle = .currency formatter.locale = Locale.current return formatter.string(from: self as NSNumber)! } }
Cela fonctionne pour swift 3.1 xcode 8.2.1
la source
Swift 4
formatter.locale = Locale.current
si vous voulez changer de langue, vous pouvez le faire comme ceci
formatter.locale = Locale.init(identifier: "id-ID")
// Il s'agit de la langue de la langue de l'Indonésie. si vous souhaitez utiliser selon la zone de téléphone mobile, utilisez-le selon la mention supérieure Locale.
//MARK:- Complete code let formatter = NumberFormatter() formatter.numberStyle = .currency if let formattedTipAmount = formatter.string(from: Int(newString)! as NSNumber) { yourtextfield.text = formattedTipAmount }
la source
ajouter cette fonction
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 }
en utilisant:
let giaTri = value as! Int myGuessTotalCorrect = addSeparateMarkForNumber(int: giaTri)
la source