I have got some strange problem while using NSMutableAttributedString for setting text part on UILabel. It shows some bizarre symbol for specific emojis. Here's the code i use and the screenshot of the problem.
guard var _comment = comment.comment ,let _username = comment.userName else { return }
var username = NSMutableAttributedString.init(string: _username)
var commentText = NSMutableAttributedString.init(string: _comment)
var commentTotal = NSMutableAttributedString.init()
commentTotal.append(username)
commentTotal.append(commentText)
self.userNameLabel.attributedText = commentTotal
Screenshot :
But if i directly put the string without using NSMutableAttributedString like this:
self.userName.text = _comment
The output of this shows the correct emoji without problem .What would be the problem here? Anyone with a suggestion?
This is the code for setting fonts :
if let font = UIFont.init(name: "Montserrat-Bold", size: self.userNameLabel.font.pointSize){
username.addAttribute(NSFontAttributeName, value: font, range: NSRange.init(location: 0, length: _username.count))
username.addAttribute(NSForegroundColorAttributeName, value: UIColor.init(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0), range: NSRange.init(location: 0, length: _username.count))
}
if let font = UIFont.init(name: "Montserrat-Medium", size: self.userNameLabel.font.pointSize-1){
commentText.addAttribute(NSFontAttributeName, value: font, range: NSRange.init(location: 0, length: commentString.count))
commentText.addAttribute(NSForegroundColorAttributeName, value: UIColor.init(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0), range: NSRange.init(location: 0, length: commentString.count))
}
Storyboard Image:
Your problem is with your NSRange
calculations when setting the attributes. NS[Mutable]AttributeString
needs the NSRange
to be based on NSString
ranges, not String
ranges.
So code like:
NSRange.init(location: 0, length: commentString.count)
Needs to be written as either:
NSRange(location: 0, length: (commentString as NSString).length)
or:
NSRange(location: 0, length: commentString.utf16.count)
The following demonstrates the issue with commentString.count
:
let comment = "💃👍👍"
print(comment.count) // 3
print((comment as NSString).length) // 6
print(comment.utf16.count) // 6
This is why your code seems to be splitting the middle character in half. You are passing in half (in this case) the needed length.
Proper way to do this in Swift 4 is using indexes on String
:
NSRange(location: 0, length: commentString.endIndex.encodedOffset)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With