I want to show a localized string in iOS that supports the following outputs:
1 mile
1.5 miles
2 miles
1,5 miles
I can use a .stringsdict file to make the pluralization work in a way that is localizable. However, I want the number passed in to have a decimal part and I only want to show 0 or 1 decimal places. Furthermore, the number should be formatted based on locale (i.e. show the correct decimal separator).
It occurs to me the solution may take one of two forms, but I can't get either working:
stringsdict alongside a string representationstringsdict using the IEEE printf specificationOkay, I actually got (1) working in the end, but it feels kind of hacky, so if anyone knows a better answer, I would still like to hear it.
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])
And the stringsdict looks like:
<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 is exactly made for this kind of thing. You can use:
let formatter = MeasurementFormatter()
formatter.unitStyle = .long
formatter.unitOptions = .providedUnit
let string = formatter.string(from: Measurement(value: 1.5, unit: UnitLength.miles))
MeasurementFormatter will handle all the plural and localisation for you.
If you only want to localise the number, but not the unit, you can set the formatter.locale to an English locale, and set formatter.numberFormatter.locale to the local locale:
formatter.locale = Locale(identifier: "en")
formatter.numberFormatter.locale = Locale.current
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With