swift - 在包含表情符号的 UITextView 中检测光标位置会在 swift 4 中返回错误的位置

标签 swift xcode uitextfield uitextview

我正在使用此代码检测光标在 UITextView 中的位置:

if let selectedRange = textView.selectedTextRange {

    let cursorPosition = textView.offset(from: textView.beginningOfDocument, to: selectedRange.start)

    print("\(cursorPosition)")
}

我把它放在 textViewDidChange 函数下,用于在每次文本更改时检测光标位置。 它工作正常,但是当我放置表情符号时,textView.text.count光标位置 不同。从 swift 4 开始,每个表情符号都算作一个字符,但似乎对于光标位置来说是不同的。

enter image description here

enter image description here

那么如何获得与文本中的字符数相匹配的准确光标位置?

最佳答案

长话短说:将 Swift 与 StringNSRange 一起使用时,请使用此扩展进行范围转换

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 中,字符串是字符的集合(ö 和 emoji 等复合字符将算作一个字符)。 UTF-8UTF-16 View 分别是UTF-8和UTF-16编码单元的集合。

你的问题是,textView.text.count 计算集合元素(表情符号和复合字符将算作一个元素)并且 NSRange 计算 UTF- 的索引16 个代码单元。上面的片段说明了差异。


更多在这里: Strings And Characters

关于swift - 在包含表情符号的 UITextView 中检测光标位置会在 swift 4 中返回错误的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52869100/

相关文章:

swift - 我迷路了...试图将用户更改的 UITextField 传递给另一个 ViewController (Swift)(Xcode6)

ios - 如何为与设备大小无关的 UICollectionView 单元格绘制网格线?

macos - 如何在 Swift 中使用 NSWindowOcclusionState.Visible

ios - 在 Swift 中以编程方式将 UIImageView 替换为 PDFView

iphone - 学习如何为 iPhone 编程的最佳 "how to"网站是什么?

ios - 试图限制 maxTextFieldLength

ios - 使用 AFNetworking 3.0,我的应用程序有一些内存泄漏

ios - xcode ios - 每当调整 slider 时更新计划计时器

ios - UITableView选中行改变 subview 背景色

ios - 将 UITextfield 设置为格式类型