How to trigger textViewdelegate on programmatical UITextView edits
Asked Answered
C

2

8

If I am typing with the keyboard, then textViewDidChange and shouldChangeTextInRange are always called. But when I change the textView programmatically, the delegate methods aren't called. How do I get a programmatic change in textView to trigger delegate methods?

Update

Is there some other way for simulating keyboard input programmatically?

Civet answered 26/9, 2014 at 9:42 Comment(8)
what exactly changed to programmatically, mean ?? ... are you sure about the delegate ?Cholula
write down the code where you are changing the text rather the calling delegatesBlew
@KumarKL it means setting the text attribute via code.Knitter
Check the textfield as set for the delegate and in .h file added the textFieldDelegate ?Cholula
The question is too simple for all these requests for clarification. It makes the people asking look like they don't know how to code or how to read. The OP is doing textView.text=@"some text"; as opposed to typing it with the keyboard. Also, @KumarKL if the delegate were not set, how would it be possible that they are called for keyboard input. Come on: just read the question. Simple.Coda
But when I change the textView programmatically,? How you are doing this .? show us some stuff.Cholula
I don't have to know the answer to find all these request ridiculous. I don't mean to hurt your ego. But the question is so clear I had to say something to stop the madness. I don't mean to pick on you, as you weren't the only one asking. But it was getting to the point where someone might come and ask what does delegate mean. Again: the question is clear!Coda
@KumarKL I am doing textView.text=@"some text" in the code. But apparently not all changes to the UITextView trigger the delegates.Civet
A
11

I solve this issue in my code using the insert method instead to change the value of the text string.

textView.insertText("Your Text")
Anything answered 13/4, 2018 at 7:38 Comment(0)
S
1

Just ran into this question a few years later but had a hard time finding other good answers, so I want to demonstrate Satheesh's technique answered here with greater detail that worked for me for future readers and people that experience a similar issue.

Technique

First, add an observer to the textView:

let property = "text" //can also be attributedText for attributed strings
self.textView.addObserver(self, forKeyPath: property, options: NSKeyValueObservingOptions(rawValue: 0), context: nil)

Next, override the observeValue function:

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

The observeValue function will run after the property value of the textView you added the observer to has been changed. Note that when you programmatically set the text of the textView like:

textView.text = "programmatically assigned text"

The shouldChangeTextIn delegate function is ran before the observer is called. As a side note, if you are using attributedText as the property, I would also recommend setting the property in that function and returning false:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        
        let newString = NSString(string: textView.text!).replacingCharacters(in: range, with: text)
        textView.attributedText = createAttributedString(text: newString)
        return false
    
}

This ensures that you do not duplicate the text you are inputting into the text and attributedText properties. You can also use the delegate function to reject input, such as new lines, and it will not call the observeValue function. To re-iterate, that function is only called after the shouldChangeTextIn function returns true or false.

If there are any mistakes here or anything else someone else would like to add, feel free to let me know.

Happy programming!

Silverware answered 6/12, 2020 at 22:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.