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!
text
attribute via code. – KnittertextView.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. – Codadelegate
mean. Again: the question is clear! – CodatextView.text=@"some text"
in the code. But apparently not all changes to the UITextView trigger the delegates. – Civet