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