【发布时间】:2019-06-06 03:59:53
【问题描述】:
我使用启用了文本属性编辑的UITextView,当文本中有表情符号时,我在获取属性时遇到问题。
这是我使用的代码:
var textAttributes = [(attributes: [NSAttributedString.Key: Any], range: NSRange)]()
let range = NSRange(location: 0, length: textView.attributedText.length)
textView.attributedText.enumerateAttributes(in: range) { dict, range, _ in
textAttributes.append((attributes: dict, range: range))
}
for attribute in textAttributes {
if let swiftRange = Range(attribute.range, in: textView.text) {
print("NSRange \(attribute.range): \(textView.text![swiftRange])")
} else {
print("NSRange \(attribute.range): cannot convert to Swift range")
}
}
当我尝试使用“示例文本❤️”之类的文本时,输出如下:
NSRange {0, 12}:示例文本
NSRange {12, 1}:无法转换为 Swift 范围
NSRange {13, 1}:无法转换为 Swift 范围
如您所见,我无法获取包含表情符号的文本。
文本属性由我在文本视图上应用的自定义NSTextStorage 设置。这是setAttributes 方法:
override func setAttributes(_ attrs: [NSAttributedString.Key: Any]?, range: NSRange) {
guard (range.location + range.length - 1) < string.count else {
print("Range out of bounds")
return
}
beginEditing()
storage.setAttributes(attrs, range: range)
edited(.editedAttributes, range: range, changeInLength: 0)
endEditing()
}
请注意,在编辑我的文本视图期间,我有一些“范围超出范围”的打印。
有没有办法将 NSRange 转换为有效的 Swift Range?
【问题讨论】:
-
“有没有办法将 NSRange 转换为有效的 Swift Range?” - 您正在使用
Range(attribute.range, in: textView.text)进行此操作。 -
guard (range.location + range.length - 1) < string.count else {必须是guard (range.location + range.length - 1) < string.utf16.count else {。 -
@rmaddy 谢谢你,
string.utf16.count工作了!但是,转换为 SwiftRange仍然会写“无法转换为 Swift 范围”。我成功地使用textView.attributedText.attributedSubstring(from: attribute.range).string -
某处你有一个
NSRange可能基于 SwiftString计数,这是错误的。从String创建NSRange时,它必须始终为.utf16.count。因此,再次展示您如何将属性应用于属性文本(并展示您如何创建范围)。 -
非常感谢,我将
NSRange中的所有.count更改为.utf16.count,它按预期工作!
标签: ios swift nsattributedstring emoji nsrange