Je crée une application de budget qui permet à l'utilisateur de saisir son budget ainsi que ses transactions. Je dois permettre à l'utilisateur de saisir à la fois des pence et des livres à partir de champs de texte distincts, qui doivent être formatés avec des symboles monétaires. Je travaille très bien pour le moment, mais j'aimerais le localiser, car il ne fonctionne actuellement qu’en GBP. Je me suis efforcé de convertir des exemples NSNumberFormatter d'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 que le symbole monétaire spécifique à l'emplacement des utilisateurs doit être ajouté. Donc, il deviendrait 10 216,32 £ ou 10 216,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.
Voici un exemple d'utilisation de 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 d'utilisation de 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 €"
J'ai également implémenté la solution fournie par @ NiñoScript comme 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)!
}
}
Utilisation:
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)!
}
}
Swift 3:
Si vous cherchez une solution qui vous donne:
Veuillez utiliser les éléments suivants:
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)"
}
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: String {
return Formatter.currency.string(for: self) ?? ""
}
var currencyUS: String {
return Formatter.currencyUS.string(for: self) ?? ""
}
var currencyBR: String {
return 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"
xCode 9.2, Swift 4
import Foundation
extension String {
var toLocale: Locale {
return Locale(identifier: self)
}
}
extension Numeric {
func currency(numberStyle: NumberFormatter.Style = NumberFormatter.Style.currency, locale: String, groupingSeparator: String? = nil, decimalSeparator: String? = nil) -> String? {
return currency(numberStyle: numberStyle, locale: locale.toLocale, groupingSeparator: groupingSeparator, decimalSeparator: decimalSeparator)
}
func currency(numberStyle: NumberFormatter.Style = NumberFormatter.Style.currency, locale: Locale = Locale.current, groupingSeparator: String? = nil, decimalSeparator: String? = nil) -> String? {
if let num = self as? NSNumber {
let formater = NumberFormatter()
formater.locale = locale
formater.numberStyle = numberStyle
var formatedSting = formater.string(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
}
}
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")
import Foundation
extension String {
var toLocale: Locale {
return Locale(identifier: self)
}
}
class NumFormatter {
static var shared = NumFormatter()
public private(set) var formater = NumberFormatter()
public private(set) var groupingSeparator: String? = nil
public private(set) var decimalSeparator: String? = nil
public var locale: Locale {
return formater.locale
}
class func locale(string: String) -> NumFormatter.Type {
NumFormatter.shared.formater.locale = string.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: String?) -> NumFormatter.Type {
NumFormatter.shared.groupingSeparator = groupingSeparator
return NumFormatter.self
}
class func number(decimalSeparator: String?) -> NumFormatter.Type {
NumFormatter.shared.decimalSeparator = decimalSeparator
return NumFormatter.self
}
}
extension Numeric {
func currency() -> String? {
if let num = self as? NSNumber {
let formater = NumFormatter.shared.formater
var formatedSting = formater.string(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
}
}
let price = 12423.42
print(price.currency() ?? "nil")
NumFormatter.number(style: .currencyISOCode)
print(price.currency() ?? "nil")
NumFormatter.locale(string: "es_ES")
print(price.currency() ?? "nil")
NumFormatter.number(groupingSeparator: "_").number(decimalSeparator: ".")
print(price.currency() ?? "nil")
Swift 4 TextField Implémenté
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
}
Swift 4
formatter.locale = Locale.current
si vous voulez changer de lieu, vous pouvez le faire comme ça
formatter.locale = Locale.init(identifier: "id-ID")
// Ceci est la locale pour la locale Indonésie. si vous voulez utiliser selon la zone de téléphone mobile, utilisez-le selon la mention supérieure Locale.current
//MARK:- Complete code
let formatter = NumberFormatter()
formatter.numberStyle = .currency
if let formattedTipAmount = formatter.string(from: Int(newString)! as
NSNumber) {
yourtextfield.text = formattedTipAmount
}
Mise à jour pour Swift 4 de @Michael Voccola's answer:
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écompression forcée, la décompression forcée est diabolique.
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)