When I set my UITextView
programmatically like this:
[self.textView setText:@""];
The delegate method textViewDidChange:
does not get called. Is there a way I can find that without making a UITextView
subclass?
When I set my UITextView
programmatically like this:
[self.textView setText:@""];
The delegate method textViewDidChange:
does not get called. Is there a way I can find that without making a UITextView
subclass?
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.
[self.textView.delegate textViewDidChange:self.textView]
, in case the delegate
changes to a different object than self
. –
Venita 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.
In swift you could override the text
variable from the UITextView
class:
class MyTextView: UITextView {
override public var text: String? {
didSet {
self.textViewDidChange(self)
}
}
}
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 {
You could also subclass UITextView and override setText to include
[self textViewDidChange:self.textView]
so that you don't have to call it every time you set the text of your UITextView.
delegate method textDidChange
does not respond to programmatical changes in textes, you can use observation to get notified
@objc dynamic
NSKeyValueObservation
observe(_:changeHandler:)
bind your text view's text property, hold the return value with variable declared in step 2example:
@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)
}
}
use this instead: (this won't reset the current text)
[self.textView insertText:@"something"];
this will call the delegate and will add text where the cursor is. Of course if you want to reset the whole text you can either:
[self.textView setText:@""];
[self textViewDidChange:self.textView];
or
[self.textView setText:@""];
[self.textView insertText:@"something"];
© 2022 - 2024 — McMap. All rights reserved.
insertText()
, however, does invoketextViewDidChange
. – Irishirishism