I want to convert a progress view's Double
value ranging from 0 to 1 into a formatted String
with a selected amount of fraction digits, e.g. 0.789123456 to "79,1 %".
Added challenge: I want to use Foundation's new FormatStyle
protocol method .formatted()
.
To my surprise, I can't get it to work. I can't find a way to specify the precision.
Here are some of my tries:
var progress: Double = 0.789123456
progress.formatted(.percent) // "78,9123456 %" it starts so easy
progress.formatted(.number.precision(.fractionLength(1))) // "0,79"
progress.formatted(.number.precision(.fractionLength(0...1))) // "0,79"
progress.formatted(.number.precision(.fractionLength(0...1))).formatted(.percent) // does not compile
// "Instance method 'formatted' requires the types 'FloatingPointFormatStyle<Double>.FormatOutput' (aka 'String') and 'FloatingPointFormatStyle<Double>.Percent.FormatInput' (aka 'Double') be equivalent"
Double(progress.formatted(.number.precision(.fractionLength(1)))) // nil
Double("0.79")?.formatted(.percent) // "79 %", gotcha, I have german Locale!
Locale.current // "en_DE (current)"
Locale.current.decimalSeparator // ","
Double(progress.formatted(.number.precision(.fractionLength(1))).replacingOccurrences(of: Locale.current.decimalSeparator!, with: ".")) // "0,8"
Double(progress.formatted(.number.precision(.fractionLength(1))).replacingOccurrences(of: Locale.current.decimalSeparator!, with: "."))?.formatted(.percent) // "80 %"
Is there a way to do this with FormatStyle
?
Or do I have to go with the old NumberFormatter
and its maximumFractionDigits
?
When using .formatted(...)
you first choose what format style to use, in this case FormatStyle.Percent
progress.formatted(.percent)
and then you can configure this format style to your liking
progress.formatted(.percent.precision(.fractionLength(1)))
Another example with a rounding rule
progress.formatted(.percent.precision(.fractionLength(1)).rounded(rule: .down))