我们使用此功能将SKProduct转换为我们的耗材包的每件商品的本地化价格:
static func pricePerUnit(_ product: SKProduct, quantity: NSDecimalNumber) -> String? {
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .currency
numberFormatter.locale = product.priceLocale
let pricePerItem = product.price.dividing(by: quantity)
guard let formattedPricePerItem = numberFormatter.string(from: pricePerItem) else {
return nil
}
return "\(formattedPricePerItem) each"
}
例如,一套10件物品,9.99英镑,英国用户为0.99英镑,美国用户为0.99美元。
理想情况下,如果金额小于单位货币(也就是1美元),我们希望它以次要货币单位显示(例如美分,便士等)。
我找不到这个或其他地方的任何答案的NumberFormatter风格。可以使用NumberFormatter完成吗?
答案 0 :(得分:1)
不幸的是,使用NumberFormatter
无法做到这一点。 NumberFormatter
使用Locale
获取货币格式,包括小数位数,正模式,负数模式,货币符号等。
(见Number Format Patterns in Unicode)
但是,小型货币的格式在Unicode中没有标准化(尽管一些必要的数据是例如乘数),并且它在iOS Locale
数据中不存在。
答案 1 :(得分:1)
NumberFormatter
可能无法直接支持格式为分和便士,但NumberFormatter
足够灵活,您可以根据自己的意愿对其进行配置。例如,可以创建一个包含2 NumberFormatter
的辅助结构:一个用美元和磅来格式化它,一个用%和便士格式化它。
struct CurrencyFormatter {
private static let defaultFormatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
return formatter
}()
private static let alternativeFormatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.multiplier = 100
return formatter
}()
static var alternativeCurrencySymbols = [
"USD": "c",
"GBP": "p"
]
static func string(from number: NSNumber, locale: Locale) -> String? {
var formatter = defaultFormatter
if number.isLessThan(1),
let currencyCode = locale.currencyCode,
let alternativeCurrencySymbol = alternativeCurrencySymbols[currencyCode]
{
formatter = alternativeFormatter
formatter.positiveSuffix = alternativeCurrencySymbol
formatter.negativeSuffix = alternativeCurrencySymbol
}
formatter.locale = locale
return formatter.string(from: number)
}
}
let number = NSNumber(value: 0.7)
let locale = Locale(identifier: "en_GB")
if let str = CurrencyFormatter.string(from: number, locale: locale) {
print(str) // result: 70p
}
该解决方案具有内置的故障安全机制。如果您还没有为货币定义替代符号,它将回退到默认货币格式。您可以通过将区域设置更改为fr_FR
来对其进行测试,结果将变为0,70 €
。