Search code examples
iosswifttextview

How to respond to programmatic changes of a TextView text


The TextView delegate is set:

textView.delegate = self //self being a UITextViewDelegate

but the delegate method doesn't get called when the text is set programmatically

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

How to respond to text changes without going reactive?


Solution

  • I just tried KVO on UITextView,

     self.textView1.text = "You are working, but I will change you in 5 seconds"
    

    Add your observer

    self.textView1.addObserver(self, forKeyPath: "text", options: NSKeyValueObservingOptions(rawValue: 0), context: nil)
    

    Trigger text change programmatically, just an example do it the way you want.

     DispatchQueue.main.asyncAfter(deadline:.now() + 5) {
        self.textView1.text = "Changed after some time"
    }
    

    Override the KVO method.

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

    FYI from Apple docs below

    Note: Although the classes of the UIKit framework generally do not support KVO, you can still implement it in the custom objects of your application, including custom views.

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