Is there a delegate call for when the text is changed on a UITextView?

When manually setting the text of a UITextView with code, the textViewDidChange: method does not get called. (If you have your text view's delegate set, it will get called when the user edits it, though.)

One possible workaround would be to manually call textViewDidChange: anytime you edit the text. For example:

[self.textView setText:@""];
[self textViewDidChange:self.textView];

Kind of a hackish way of doing it, but it gets the job done.


In swift you could override the text variable from the UITextView class:

class MyTextView: UITextView {

    override public var text: String? {
        didSet {
            self.textViewDidChange(self)
        }
    }

}

I upvoted @rebello95's response because it is one approach. But another, less hacky approach is to do as

- (void)whereIManuallyChangeTextView
{//you don't actually have to create this method. It's simply wherever you are setting the textview to empty
  [self.textView setText:@""];
  [self respondToChangeInTextView:self.textView];
}
    
- (void)textViewDidChange:(UITextView *)textView
{
  //...some work and then
  [self respondToChangeInTextView:textView];
}
    
- (void)respondToChangeInTextView:(UITextView *)textView
{
  //what you want to happen when you programmatically/manually or interactively change the textview
}

This snippet exemplifies a respectable pattern that will make your code more readable.


Old post, but I had the same problem and thought I would share my solution (in Swift).

textViewDidChange(_ textView: UITextView) does not get called by just setting the text property, but it does get called when using replace(range: UITextRange, withText: String). So you need to create a UITextRange for the entire string of the UITextView and replace it with a new string.

// Create a range of entire string
let textRange = textView.textRange(from: textView.beginningOfDocument, to: textView.endOfDocument)
// Create a new string
let newText = ""
// Call Replace the string in your textView with the new string
textView.replace(textRange!, withText: newText)

That should do it. Of course, you need to set up UITextViewDelegate for this to work:

class ViewController: UIViewController, UITextViewDelegate {