我有一个我正在构建的库,需要跟踪文本输入到UITextView中,以便跟踪文本某些部分的位置。大多数情况在textView(_:shouldChangeTextIn:replacementText:)
方法中处理得很好。我遇到的问题是某些键盘具有字符组合,实际上会更改字符而不调用textView(_:shouldChangeTextIn:replacementText:)
方法。一个简单的例子就是如果你选择一个越南语键盘并输入uw
它将改为ú
但是对textView(_:shouldChangeTextIn:replacementText:)
的唯一调用将是u和w的输入。此时偏移计算将不正确。据我所知,没有其他方法可以用来了解这一变化。我不确定这是不是一个bug。将调用textViewDidChange方法,但我希望避免使用hacky逻辑,我将textView的前一个文本和新文本进行比较,以确定任何更改并调整逻辑。如果有人有建议我会很乐意听到他们。希望有人看到并解决了这个问题。谢谢。
为了澄清,我需要使用子类以外的东西来处理这种情况。
示例项目:https://github.com/szweier/ShouldChangeTextInRange如果您运行上面的代码并选择越南键盘输入uw
,您将看到textView(_:shouldChangeTextIn:replacementText:)
方法中生成的字符串将与textView中的文本不同。
据我所知,UITextView
或它的代表没有shouldReplaceCharacters
API(我也没有谷歌搜索任何有用的东西,至少对iOS来说 - it does exist for macOS though)
如果我继承UITextView
,我可以覆盖insertText
并检测真正的插入点是什么:
class TestTextView : UITextView {
override func insertText(_ text: String) {
let selectedRange = self.selectedRange
if let markedRange = self.markedTextRange {
Swift.print("TestTextView inserting \(text) at \(selectedRange.location) & \(selectedRange.length) ; marked = \(markedRange.start) & \(markedRange.end)")
} else {
Swift.print("TestTextView inserting \(text) at \(selectedRange.location) & \(selectedRange.length) and no marked range")
}
super.insertText(text)
}
}
当我将这个子类TestTextView
添加到测试项目并打开VN键盘时。这是我在uw
中输入的内容:
TestTextView inserting u at 17 & 0 and no marked range
TestTextView inserting ư at 17 & 0 and no marked range
而“e”和“b”顺序输入如下:
TestTextView inserting e at 17 & 0 and no marked range
TestTextView inserting b at 18 & 0 and no marked range
最后,我的答案很简单,你可能需要keep track of "marked text range", which comes into play with this multistage text input。