我正在使用此代码来检测光标在UITextView
中的位置:
if let selectedRange = textView.selectedTextRange {
let cursorPosition = textView.offset(from: textView.beginningOfDocument, to: selectedRange.start)
print("\(cursorPosition)")
}
我将其放在textViewDidChange
函数下,以在每次文本更改时检测光标位置。
它工作正常,但是当我放置表情符号时, textView.text.count 与光标位置不同。从迅速4开始,每个表情符号都算作一个字符,但对于光标位置来说似乎是不同的。
那么如何获得与文本中字符数匹配的确切光标位置?
答案 0 :(得分:2)
长话短说:将Swift与String
和NSRange
结合使用时,请将此扩展名用于范围转换
extension String {
/// Fixes the problem with `NSRange` to `Range` conversion
var range: NSRange {
let fromIndex = unicodeScalars.index(unicodeScalars.startIndex, offsetBy: 0)
let toIndex = unicodeScalars.index(fromIndex, offsetBy: count)
return NSRange(fromIndex..<toIndex, in: self)
}
}
让我们更深入地了解一下:
let myStr = "Wéll helló ⚙️"
myStr.count // 12
myStr.unicodeScalars.count // 13
myStr.utf8.count // 19
myStr.utf16.count // 13
在 Swift 4 字符串中是字符的集合(如ö这样的复合字符,表情符号将被视为一个字符)。 UTF-8 和 UTF-16 视图分别是UTF-8和UTF-16代码单元的集合。
您的问题是, textView.text.count 计算集合元素(表情符号和复合字符将作为一个元素),而NSRange
计算UTF-16代码单元的索引。上面的片段说明了差异。
更多信息: Strings And Characters