如果是 0

问题描述

我是 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) ?? ""
}