UITextView 观察文字变化
UITextView observe text changes
我想监听 UITextView 中的每个文本更改。设置非常简单。
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(
self,
selector: #selector(textViewDidChangeWithNotification(_:)),
name: UITextView.textDidChangeNotification,
object: nil
)
}
@objc private func textViewDidChangeWithNotification(_ notification: Notification) {
print("Text: \(String(describing: inputTextView.text))")
}
在大多数情况下它工作正常,但后来我发现了一些 UITextInput 的黑盒魔法。
第 1 步: 'I' 输入。我们可以在输出中看到 'I'。
第 2 步:重要的一步。 Select 在字段上双击所有文本。
第 3 步: Select 'If' 来自单词建议。
并且调试器输出中没有 'If'。另一方面,如果插入符号位于 'I' 单词的末尾,我们 select 'If' 输出结果是正确的。
有什么方法可以观察所有文本变化吗?
我可以通过以下方式获取文本:
func textViewDidEndEditing(_ textView: UITextView)
但我需要实时观察所有变化。我经常看到的另一个选项是使用:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool
但是这种观察变化的方法是不好的做法。如果你重复输入两个 spaces iOS 将用点替换第一个 space 并且显然不会通知你此方法中的此操作以及它的许多其他问题。
您可以使用 func textViewDidChangeSelection(_ textView: UITextView)
检测选择的变化 ?
如果你想听每一个变化 shouldChangeTextIn
是要走的路。可以写条件解决与之相关的问题
好的,经过大量研究后,我尝试了 RxSwift,因为我认为在反应式范式框架中观察文本应该在 100% 的情况下成功。而且它没有任何问题!
inputTextView.rx.text.subscribe(onNext: { string in
print("rx: \(string)")
})
看来这些家伙已经找到了解决办法。
https://github.com/ReactiveX/RxSwift/blob/master/RxCocoa/iOS/UITextView%2BRx.swift
这里的解决方案可以为您提供有关所有文本更改的信息,尽管有自动更正、文本选择等。
class ViewController: UIViewController {
@IBOutlet weak var inputTextView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
inputTextView.textStorage.delegate = self
}
}
extension ViewController: NSTextStorageDelegate {
func textStorage(_ textStorage: NSTextStorage, didProcessEditing editedMask: NSTextStorage.EditActions, range editedRange: NSRange, changeInLength delta: Int) {
print("string: \(textStorage.string)")
}
}
我想监听 UITextView 中的每个文本更改。设置非常简单。
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(
self,
selector: #selector(textViewDidChangeWithNotification(_:)),
name: UITextView.textDidChangeNotification,
object: nil
)
}
@objc private func textViewDidChangeWithNotification(_ notification: Notification) {
print("Text: \(String(describing: inputTextView.text))")
}
在大多数情况下它工作正常,但后来我发现了一些 UITextInput 的黑盒魔法。
第 1 步: 'I' 输入。我们可以在输出中看到 'I'。
第 2 步:重要的一步。 Select 在字段上双击所有文本。
第 3 步: Select 'If' 来自单词建议。
并且调试器输出中没有 'If'。另一方面,如果插入符号位于 'I' 单词的末尾,我们 select 'If' 输出结果是正确的。
有什么方法可以观察所有文本变化吗?
我可以通过以下方式获取文本:
func textViewDidEndEditing(_ textView: UITextView)
但我需要实时观察所有变化。我经常看到的另一个选项是使用:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool
但是这种观察变化的方法是不好的做法。如果你重复输入两个 spaces iOS 将用点替换第一个 space 并且显然不会通知你此方法中的此操作以及它的许多其他问题。
您可以使用 func textViewDidChangeSelection(_ textView: UITextView)
检测选择的变化 ?
如果你想听每一个变化 shouldChangeTextIn
是要走的路。可以写条件解决与之相关的问题
好的,经过大量研究后,我尝试了 RxSwift,因为我认为在反应式范式框架中观察文本应该在 100% 的情况下成功。而且它没有任何问题!
inputTextView.rx.text.subscribe(onNext: { string in
print("rx: \(string)")
})
看来这些家伙已经找到了解决办法。
https://github.com/ReactiveX/RxSwift/blob/master/RxCocoa/iOS/UITextView%2BRx.swift
这里的解决方案可以为您提供有关所有文本更改的信息,尽管有自动更正、文本选择等。
class ViewController: UIViewController {
@IBOutlet weak var inputTextView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
inputTextView.textStorage.delegate = self
}
}
extension ViewController: NSTextStorageDelegate {
func textStorage(_ textStorage: NSTextStorage, didProcessEditing editedMask: NSTextStorage.EditActions, range editedRange: NSRange, changeInLength delta: Int) {
print("string: \(textStorage.string)")
}
}