I am trying to use NumberFormatter() to create a string representation of CGFloats. Ideally, I would like to create a signed string like transforming a value of
10.1
-> " 10.1"
and
-10.1
-> "- 10.1"
, the integer part being padded with spaces.
This is the closest I have gotten, but it pads the integer portion with "0" so I get
10.1
-> " 010.1"
and
-10.1
to "-010.1"
If I don't use .minimumIntegerDigits
there is no padding.
I'm using a monospaced font to display the values and I'm trying to make sure they don't get jiggly as they change, and I was just hoping there would be some way to use a space in place of the 0 but otherwise exactly how .minimumIntegerDigits
works.
extension CGFloat {
func signedPaddedString() -> String {
let formatter = NumberFormatter()
formatter.positivePrefix = " "
formatter.minimumIntegerDigits = 3
formatter.paddingCharacter = " "
formatter.minimumFractionDigits = 1
formatter.maximumFractionDigits = 1
return formatter.string(from: self as NSNumber)!
}
}
You can achieve this by setting the positiveFormat
and negativeFormat
properties, which are format patterns according to the Unicode Technical Standard #35:
extension FloatingPoint {
func signedPaddedString() -> String {
let formatter = NumberFormatter()
formatter.positiveFormat = " * ##0.0"
formatter.negativeFormat = "-* ##0.0"
return formatter.string(for: self)!
}
}
print((10.1).signedPaddedString()) // " 10.1"
print((-10.1).signedPaddedString()) // "- 10.1"
print((123.45).signedPaddedString()) // " 123.4"
print((-123.45).signedPaddedString()) // "-123.4"
print((0).signedPaddedString()) // " 0.0"
print((-1).signedPaddedString()) // "- 1.0"
If you want to suppress localization (e.g. in countries using decimal comma) then add
formatter.locale = Locale(identifier: "en_US_POSIX")