问题描述
我是 Swift 的新手,请耐心等待。 :)
我无法将输出货币显示为两位小数。目前,它只显示一位小数。例如,如果我输入 $1.10,则输出为 $1.1。
然而,如果我输入 1.11 美元,输出仍然是 1.11 美元。
func currencyInputDoubling() -> String {
var number: NSNumber!
let formatter = NumberFormatter()
formatter.numberStyle = .currencyAccounting
formatter.currencySymbol = CurrencyManager.shared.currentCurrency.sign
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
var amountWithPrefix = self
// remove from String: "$",".",","
let regex = try! NSRegularExpression(pattern: "[^0-9]",options: .caseInsensitive)
amountWithPrefix = regex.stringByReplacingMatches(in: amountWithPrefix,options: NSRegularExpression.MatchingOptions(rawValue: 0),range: NSMakeRange(0,self.count),withTemplate: "")
let double = (amountWithPrefix as Nsstring).doubleValue
number = NSNumber(value: (double / 100))
// if first number is 0 or all numbers were deleted
guard number != 0 as NSNumber else {
return ""
}
return "\(double / 100)"
}
解决方法
我建议使用 Locale 而不是 currencySymbol 并创建可以重复使用的静态数字格式化程序。
let currencyFormatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = .current
return formatter
}()
let numberFormatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.locale = .current
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2
return formatter
}()
然后方法可以简化为
func currencyInputDoubling(_ amountWithPrefix: String) -> String {
guard let value = currencyFormatter.number(from: amountWithPrefix) else { return "" }
return numberFormatter.string(from: value) ?? ""
}
如果您需要将 Locale 设置为 .current 以外的其他内容,您可以将其作为参数传递
func currencyInputDoubling(_ amountWithPrefix: String,using locale: Locale) -> String {
currencyFormatter.locale = locale
numberFormatter.locale = locale
guard let value = currencyFormatter.number(from: amountWithPrefix) else { return "" }
return numberFormatter.string(from: value) ?? ""
}
,
我建议至少使用您创建的格式化程序,而不是进行字符串插值。当您使用简单的字符串插值返回 "\(double / 100)"
时,它无法利用格式化程序的小数位数设置。
也许:
func currencyInputDoubling() -> String {
let formatter = NumberFormatter()
formatter.numberStyle = .currencyAccounting
formatter.currencySymbol = CurrencyManager.shared.currentCurrency.sign
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
// remove from String: "$",".",","
let digitsOnly = filter("0123456789".contains)` // or,if you want to use regex,simply `let digitsOnly = replacingOccurrences(of: "[^0-9]",with: "",options: .regularExpression)`
// return formatted string
guard let value = Double(digitsOnly) {
return ""
}
return formatter.string(for: value / 100) ?? ""
}