首页 > 解决方案 > Swift:maximumFractionDigits 在更改货币时无法按预期工作

问题描述

我将 Swift 的 NumberFormatter 与货币 numberStyle 一起使用。我设置了以下属性:

let value: Double = 345.23
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = 0
formatter.locale = Locale(identifier: "en_US")
formatter.currencyCode = "USD"
print(formatter.string(from: NSNumber(value: value))) //Will print $345 as expected

如果我更改货币并再次打印,我会得到两位小数。为什么?

formatter.currencyCode = "EUR"
print(formatter.string(from: NSNumber(value: value))) //Will print €345.23 with two decimals

这是应该发生的还是它是一个错误?如果我将语言环境更改为其他内容,例如“fr_FR”,然后再次返回“en_US”,它将以 0 位小数打印。请参阅 XCTestCase 的附加结果。只有当语言环境被修改时,货币才会有预期的小数位数。

CurrencyNumberFormatter 测试

更新:它适用于 iOS 13.3,但不适用于 iOS 12.0 和 11.0.1

标签: swiftlocalecurrencynumberformatter

解决方案


如果您在不更改的情况下执行代码minimumFractionDigitsmaximumFractionDigits您会注意到这些设置已使用与每种货币关联的默认值重新初始化:

// My favourite test currencies with 2, 3, 2 and 0 decimals
for mycur in ["USD", "TND", "EUR", "JPY" ] {
    myformatter.currencyCode = mycur
    print ("cur:\(mycur): min:\(myformatter.minimumFractionDigits) max:\(myformatter.maximumFractionDigits) result:\(myformatter.string(from: NSNumber(value: value)) ?? "xxx")")
}

此代码产生以下结果:

cur:USD: min:2 max:2 result:$345.23
cur:TND: min:3 max:3 result:TND 345.230
cur:EUR: min:2 max:2 result:€345.23
cur:JPY: min:0 max:0 result:¥345

NumberFormatter顺便说一句,一旦您使用默认语言环境的货币设置为您选择货币样式,这些设置就会被初始化。而且每次更改区域设置也可能会更改货币以及这些相关设置。

现在我无法用我当前安装的版本重现您的问题:只要我更改一次minimumFractionDigitsmaximumFractionDigits,无论货币如何变化,它都会保留新设置。(此行为也与当前货币的设置或默认设置无关)。

但是看看你的问题描述,很有可能NumberFormatter在之前的版本中没有跟踪设置的显式更改,并且它在每次货币更改时系统地重新加载了默认货币设置。

然后,版本独立的解决方法是在您每次更改区域设置或货币时重新应用您的临时设置。


推荐阅读