Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

End of NSAttributedString with emojis left unformatted

The end of my NSAttributedString with emojis in the contents is not being formatted. I'm trying to format the entire string (set the text color to white in this example, for simplification), but some of the text stays unformatted when put in a UILabel.

enter image description here

Currently, I'm using

let attributedString = NSMutableAttributedString(string: contents)

attributedString.addAttribute(
    NSForegroundColorAttributeName,
    value: UIColor.white,
    range: NSMakeRange(0, contents.characters.count)
)

label.attributedText = attributedString

I've also tried getting the length by using contents.utf8.count but get the same result.

I noticed that the number of unformatted characters is the same as the number of emojis in the string. Could that have something to do with what's going on?

like image 727
Jojodmo Avatar asked Jun 26 '15 20:06

Jojodmo


1 Answers

String.characters.count returns the number of rendered characters in the string. Some emojis (such as flags and race-specific ones) are a combination of two or more UTF characters that are rendered into one character, in order to allow for more emojis.

UTF stands for Unicode Transformation format, or Unicode for short. It allows for computers, phones, tablets, and everything else electronic to use the same standardized set of characters.

Those who implement it can chose how to render the text, but it is massively important that devices communicate using a standardized character set. Otherwise, sending the message "Hello, World" to someone may show up as "Ifmmp, Xpsme"

In order to get the actual length of the string for use in NSMakeRange, use NSAttributedString.length or Int("\(contents.endIndex)").

So, the code should look like this

let attributedString = NSMutableAttributedString(string: contents)

attributedString.addAttribute(
    NSForegroundColorAttributeName,
    value: UIColor.white,
    range: NSMakeRange(0, attributedString.length)
)

label.attributedText = attributedString

This will now produce the correctly formatted text

enter image description here

like image 156
Jojodmo Avatar answered Oct 16 '22 10:10

Jojodmo