同时使用复数字符串和数字格式化程序

Using a pluralized string and a number formatter at the same time

我想在 iOS 中显示支持以下输出的本地化字符串:

1 mile

1.5 miles

2 miles

1,5 miles

我可以使用 .stringsdict 文件以可本地化的方式进行复数化。但是,我希望传入的数字有小数部分,我只想显示 0 或 1 位小数。此外,数字应根据语言环境进行格式化(即显示正确的小数点分隔符)。

我想到解决方案可能采用两种形式之一,但我无法使任何一种工作:

  1. 将数字表示与字符串表示一起传递给 stringsdict
  2. 使用 IEEE printf 规范格式化 stringsdict 中的数字

好吧,最后我实际上得到了 (1) 工作,但感觉有点 hacky,所以如果有人知道更好的答案,我仍然想听听。

let miles: Double = 1.5

let formatter = NumberFormatter()
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = 1
let milesString = formatter.string(from: NSNumber(value: miles))!

let formatString = NSLocalizedString("key", comment: "")
let string = String(format: formatString, arguments: [miles, milesString])

stringsdict 看起来像:

<dict>
        <key>key</key>
        <dict>
                <key>NSStringLocalizedFormatKey</key>
                <string>%1$#@miles@</string>
                <key>miles</key>
                <dict>
                        <key>NSStringFormatSpecTypeKey</key>
                        <string>NSStringPluralRuleType</string>
                        <key>NSStringFormatValueTypeKey</key>
                        <string>f</string>
                        <key>one</key>
                        <string>1 mile</string>
                        <key>other</key>
                        <string>%2$@ miles</string>
                </dict>
        </dict>
</dict>

MeasurementFormatter就是为这种东西而生的。您可以使用:

let formatter = MeasurementFormatter()
formatter.unitStyle = .long
formatter.unitOptions = .providedUnit
let string = formatter.string(from: Measurement(value: 1.5, unit: UnitLength.miles))

MeasurementFormatter 将为您处理所有复数和本地化。

如果你只想本地化数字,而不是单位,你可以将 formatter.locale 设置为英语语言环境,并将 formatter.numberFormatter.locale 设置为本地语言环境:

formatter.locale = Locale(identifier: "en")
formatter.numberFormatter.locale = Locale.current