Phantom spaces in UILabel's text
Yesterday, I posted an article about how I apparently found a bug in NSAttributedString, happening only on device. I was wrong. There’s no bug, only me being tired (I posted that article at 4am) and not looking for source of the issue hard enough. Here’s what really happened.
While working on Today extension for Banca, I encountered an issue that killed me at least a day or so of productivity. I have a table cell that looks like this:
Right-hand labels have NSTextAlignmentRight
set on them and it worked fairly well during inital spec-ing of the cell and even during entire development in the Simulator. It went downhill as I moved to my iPhone.
Here’s how the labels aligned in the iOS 8 Simulator:
As expected and designed. And here’s on the iOS 8 device:
So, where did that space on the right of the number come up? After trying any imaginable trickery, I eventually outputed the result value. On simulator it looked like this:
Nothing suspicious. However…
…on device, at the end of the value, there’s a strange looking dot. This is non-breaking space character and I suspect Xcode displays this as dot only because I’m using Inconsolata as console font. This character is also transfered to NSString
if you do [result stringValue]
:
The fix is simple, just remove the space.
[[toValue string] stringByReplacingOccurrencesOfString:@" " withString:@""]
However - where did this come from? That value I display there, it’s basically a currency value. Banca allows you to convert from any currency to any other. It’s good and expected practice to display values in the user’s currently chosen regional settings, which in iOS you access through NSLocale
. Thus my formatter is set like this:
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[formatter setLocale:[NSLocale currentLocale]];
This will give you a nice value like “1.412,39 din.” if you are converting to Serbian currency (RSD), all correctly formatted. Since in Banca I already separatelly show the currency code, I added this to remove the currency symbol:
[formatter setCurrencySymbol:@""];
And that’s where my trouble is. Depending on the chosen regional settings on the actual device, I may or may not have a space either before or after the currency value. German settings would return “€234.48” and all is fine, but Serbian settings which I use on my iPhone would yield the non-breaking-space that Apple rightly uses (to keep the number connected with the symbol). Simulator of course uses default US settings.
Thus there’s not a bug anywhere, it all works as designed. This is simply an oversight in my code.