在给 nsmutableattr
在给 NSMutableAttributedString 对象添加属性时,如果文本中含有 Emoji 表情,则会出现乱码的情况
在给 NSMutableAttributedString 对象添加属性时,如果文本中含有 Emoji 表情,则会出现乱码的情况。这是因为 Emoji 表情使用了 Unicode 码点,但是一个 Emoji 表情可能由多个 Unicode 码点组成,当使用 addAttribute(_:value:range:) 方法时,只有第一个码点才会被正确识别,其他码点则会被解析错误,从而导致乱码现象。
要解决这个问题,我们可以使用 NSAttributedString 的 enumerateAttributes(in:options:using:) 方法,逐个遍历文本中所有的 NSAttributedString.Key 属性,并对其进行设置。
以下是一个示例代码:
let str = "Hello 😀 World 🌎"
let attributedString = NSMutableAttributedString(string: str)
attributedString.addAttributes([.foregroundColor: UIColor.red], range: NSRange(location: 0, length: str.count))
attributedString.enumerateAttributes(in: NSRange(location: 0, length: attributedString.length), options: []) { (attributes, range, _) in
var newAttributes = attributes
// Check if the current attribute is a foreground color
if let foregroundColor = attributes[NSAttributedString.Key.foregroundColor] as? UIColor {
// Create a new foreground color with the same color space as the original
let newForegroundColor = foregroundColor.converted(to: CGColorSpaceCreateDeviceRGB(), intent: .defaultIntent, options: nil)!
// Update the attribute with the new foreground color
newAttributes[NSAttributedString.Key.foregroundColor] = newForegroundColor
// Apply the new attribute to the range
attributedString.setAttributes(newAttributes, range: range)
}
}
在这个代码中,我们首先创建了一个包含 Emoji 表情的字符串,并将其转换为 NSMutableAttributedString 对象。然后,我们使用 addAttributes(_:value:range:) 方法添加了前景色属性 foregroundColor。
接着,我们使用 enumerateAttributes(in:options:using:) 方法遍历所有属性,当遇到前景色属性时,我们将其颜色空间转换为设备 RGB 颜色空间,并将其设置为新的前景色属性值,最后再用 setAttributes(_:range:) 方法将新属性应用到文本的相应位置。
或者在构造 NSMutableAttributedString 时传入 attributes 也可以避免这个问题, 如:NSMutableAttributedString(string: str, attributes: attributes)。
