Reputation: 553
This is the most weird problem (XCode 10.2.1 playground):
let a = "String with emoji π"
var b = "00:00 0000"
var nsa = NSMutableAttributedString(string: a)
var nsb = NSMutableAttributedString(string: b)
nsb.addAttributes([.foregroundColor: UIColor.red],
range: NSRange(location: 0, length: nsb.length))
nsa.append(nsb)
and the nsa
looks like this:
The 00
after the emoji has the same width and height as the emoji character. But it gets weirder. The effect is extended only over digits 0-9, space, and hash (#) characters. If I replace the 00:00 0000
with a different string then everything is perfectly normal:
It seems like internally NSMutableAttributedString
applies an attribute to the emoji character and then incorrectly extends it to the attached string's prefix composed of certain characters.
Is this a known problem? I found a workaround by appending a thin non-breaking space character to the first string a + "\u{2009}"
. Is there a better way of dealing with emoji weirdness in Swift?
Upvotes: 4
Views: 860
Reputation: 553
Here is Apple's official answer:
We have determined that this is an issue for you to resolve.
Since the app is not explicitly specifying the font to the attributed string, itβs relying on the font fallback system.
It is recommended to specify the font attribute all the time since the contextual nature of the text system might produce unexpected result like this.
Please let us know whether the issue is resolved for you by updating your bug report.
This is just appalling.
Upvotes: -1
Reputation: 318954
The display issue happens in the playground display of the attributed string. It also happens if you use the attributed string in a UITextView. But the problem does not happen in a UILabel.
All of the display issues go away if you give the attributed string a font.
Adding:
nsa.addAttributes([.font: UIFont.systemFont(ofSize: 16)],
range: NSRange(location: 0, length: nsa.string.utf16.count))
after appending the two strings makes the all of the issues go away. Obviously you should use whatever desired font you want.
You should always apply a font to an attributed string so the UI components know how to properly display the content of the attribute string.
Upvotes: 2