如何响应TextView文本的程序化更改

3

设置了TextView委托:

textView.delegate = self //self being a UITextViewDelegate

但是当文本以编程方式设置时,委托方法不会被调用。

func textViewDidChange(_ textView: UITextView) {
    print(textView.text)
}

如何在不使用响应式的情况下响应文本更改?

你可能需要在改变文本的任何函数中添加一些内容... 或者,可能要子类化UITextView并添加自己的“监视更改”的代码。 - DonMag
4个回答

3
这就是UITextField(以及大多数UIKit控件)的行为方式- 当以编程方式设置时不会触发事件。这是有道理的- 可以避免反复、无限制的调用。
如果您真的想在程序中通知文本已更改,您必须对UITextField进行子类化,并覆盖text属性(可能还包括attributedText)。然后在didSet块中调用委托方法。
不要忘记,UITextField继承自UIControl- 我也会调用sendActions(for:)来触发目标-动作机制。

原帖问题是关于 UITextView,而不是 UITextField。大部分回答都是相关的,但不幸的是,UITextView并未继承自 UIControl,因此无法调用 sendActions(for:) - Jay Whitsitt

3
我刚刚在UITextView上尝试了KVO。
 self.textView1.text = "You are working, but I will change you in 5 seconds"

添加您的观察者。
self.textView1.addObserver(self, forKeyPath: "text", options: NSKeyValueObservingOptions(rawValue: 0), context: nil)

通过程序触发文本更改,这只是一个示例,可以按你想要的方式执行。
 DispatchQueue.main.asyncAfter(deadline:.now() + 5) {
    self.textView1.text = "Changed after some time"
}

覆盖 KVO 方法。
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if object == self.textView1{
     //do your thing here...
    }
}

来自苹果文档的信息如下:
请注意:尽管 UIKit 框架的类通常不支持 KVO,但您仍然可以在应用程序的自定义对象(包括自定义视图)中实现它。

https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/KVO.html


0
  1. 使用@objc dynamic声明您的文本视图变量。
  2. 使用类型NSKeyValueObservation声明并保存一个变量。
  3. 使用函数observe(_:changeHandler:)绑定您的文本视图的文本属性,并使用在步骤2中声明的变量保存返回值。
  4. changeHandler中观察变化。

例如:

@objc dynamic private var textView: UITextView!
private var observation: NSKeyValueObservation?

func bind() {
    observation = observe(\.textView.text, options: [.old, .new]) { object, change in
        print(object, change)
    }
}

-2

你把代理的textView拼成了_textView。

func textViewDidChange(textView: UITextView) { //Handle the text changes here
        print(textView.text); //the textView parameter is the textView where text was changed
    }

将此代码放入viewDidLoad方法中。
textView!.delegate = self

没错,Swift 3.0/3.1要求使用该签名。 - Satheesh
@Saranjith 不是的。这是Swift 3+上的正确签名。 - ielyamani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接