在 UILabel 上使用 NSMutableAttributedString 时表情符号丢失
Emoji loss when using NSMutableAttributedString on UILabel
我在使用 NSMutableAttributedString 设置 UILabel 上的文本部分时遇到了一些奇怪的问题。它为特定的表情符号显示了一些奇怪的符号。这是我使用的代码和问题的屏幕截图。
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
截图:
但是如果我不使用 NSMutableAttributedString 直接输入字符串,就像这样:
self.userName.text = _comment
这个输出显示正确的表情符号没有问题
.这里会有什么问题?有人有建议吗?
这是设置字体的代码:
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))
}
故事板图片:
您的问题出在设置属性时的 NSRange
计算上。 NS[Mutable]AttributeString
需要 NSRange
基于 NSString
范围,而不是 String
范围。
所以代码如下:
NSRange.init(location: 0, length: commentString.count)
需要写成:
NSRange(location: 0, length: (commentString as NSString).length)
或:
NSRange(location: 0, length: commentString.utf16.count)
以下说明了 commentString.count
的问题:
let comment = ""
print(comment.count) // 3
print((comment as NSString).length) // 6
print(comment.utf16.count) // 6
这就是为什么您的代码似乎将中间字符分成两半的原因。您正在传递所需长度的一半(在这种情况下)。
在 Swift 4 中执行此操作的正确方法是在 String
:
上使用索引
NSRange(location: 0, length: commentString.endIndex.encodedOffset)
我在使用 NSMutableAttributedString 设置 UILabel 上的文本部分时遇到了一些奇怪的问题。它为特定的表情符号显示了一些奇怪的符号。这是我使用的代码和问题的屏幕截图。
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
截图:
但是如果我不使用 NSMutableAttributedString 直接输入字符串,就像这样:
self.userName.text = _comment
这个输出显示正确的表情符号没有问题
.这里会有什么问题?有人有建议吗?
这是设置字体的代码:
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))
}
故事板图片:
您的问题出在设置属性时的 NSRange
计算上。 NS[Mutable]AttributeString
需要 NSRange
基于 NSString
范围,而不是 String
范围。
所以代码如下:
NSRange.init(location: 0, length: commentString.count)
需要写成:
NSRange(location: 0, length: (commentString as NSString).length)
或:
NSRange(location: 0, length: commentString.utf16.count)
以下说明了 commentString.count
的问题:
let comment = ""
print(comment.count) // 3
print((comment as NSString).length) // 6
print(comment.utf16.count) // 6
这就是为什么您的代码似乎将中间字符分成两半的原因。您正在传递所需长度的一半(在这种情况下)。
在 Swift 4 中执行此操作的正确方法是在 String
:
NSRange(location: 0, length: commentString.endIndex.encodedOffset)