Estoy creando una aplicación de presupuesto que le permite al usuario ingresar su presupuesto y transacciones. Necesito permitir que el usuario ingrese peniques y libras desde campos de texto separados y deben formatearse junto con los símbolos de moneda. Tengo esto funcionando bien en este momento, pero me gustaría localizarlo, ya que actualmente solo funciona con GBP. He estado luchando para convertir ejemplos de NSNumberFormatter de Objective C a Swift.
Mi primer problema es el hecho de que necesito establecer los marcadores de posición para que los campos de entrada sean específicos de la ubicación de los usuarios. P.ej. Libras y peniques, dólares y centavos, etc.
El segundo problema es que los valores ingresados en cada uno de los campos de texto, como 10216 y 32, deben formatearse y el símbolo de moneda específico para la ubicación del usuario debe agregarse. Entonces se convertiría en £ 10,216.32 o $ 10,216.32, etc.
Además, necesito usar el resultado del número formateado en un cálculo. Entonces, ¿cómo puedo hacer esto sin tener problemas sin tener problemas con el símbolo de moneda?
Cualquier ayuda será muy apreciada.
fuente
Respuestas:
Aquí hay un ejemplo sobre cómo usarlo en Swift 3. ( Editar : también funciona en 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 €"
Aquí está el viejo ejemplo sobre cómo usarlo en 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 €"
fuente
string(for: price)
lugar destring(from: price)
Swift 3:
Si buscas una solución que te brinde:
Utilice lo siguiente:
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)" }
fuente
func string(for obj: Any?) -> String?
lugar delstring(from:)
También he implementado la solución proporcionada por @ NiñoScript como una extensión:
Extensión
// 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)! } }
Uso:
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)! } }
fuente
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"
fuente
Detalles
Solució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 } }
Uso
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")
Resultados
$12,423.42 USD12,423.42 12.423,42 € 12 423,42 EUR 12_423.42 US dollars 12 423,42 Euro
fuente
Actualizado para Swift 4 de la respuesta 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 ?? "" } }
Nota: no hay desenvolvimientos forzados, desenvolvimientos forzados son malos.
fuente
Swift 4 TextField implementado
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 }
fuente
extension Float { var convertAsLocaleCurrency :String { var formatter = NumberFormatter() formatter.numberStyle = .currency formatter.locale = Locale.current return formatter.string(from: self as NSNumber)! } }
Esto funciona para swift 3.1 xcode 8.2.1
fuente
Rápido 4
formatter.locale = Locale.current
si desea cambiar la configuración regional, puede hacerlo así
formatter.locale = Locale.init(identifier: "id-ID")
// Esta es la configuración regional de Indonesia. si desea usarlo según el área del teléfono móvil, utilícelo según la mención superior Locale.current
//MARK:- Complete code let formatter = NumberFormatter() formatter.numberStyle = .currency if let formattedTipAmount = formatter.string(from: Int(newString)! as NSNumber) { yourtextfield.text = formattedTipAmount }
fuente
agregar esta función
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 }
utilizando:
let giaTri = value as! Int myGuessTotalCorrect = addSeparateMarkForNumber(int: giaTri)
fuente