Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
313 views
in Technique[技术] by (71.8m points)

swift - Second decimal place gets truncated if it is 0

I'm new to Swift, so bear with me. :)

I'm having trouble showing the output currency to two decimal places. Currently, it only shows one decimal place. For example, if I input $1.10, the output is $1.1.

However, if I input $1.11, the output is still $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)"
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I would suggest using Locale instead of currencySymbol and to create static number formatters that can be reused.

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
}()

And then the method can be simplified as

func currencyInputDoubling(_ amountWithPrefix: String) -> String {
    guard let value = currencyFormatter.number(from: amountWithPrefix) else { return "" }

    return numberFormatter.string(from: value) ?? ""
}

If you need to set Locale to something else than .current you could pass it as an argument

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...