Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UITextView.rx_text doesn't catch iOS autocorrect text changes #333

Closed
timojaask opened this issue Dec 11, 2015 · 13 comments
Closed

UITextView.rx_text doesn't catch iOS autocorrect text changes #333

timojaask opened this issue Dec 11, 2015 · 13 comments
Labels

Comments

@timojaask
Copy link

UITextView.rx_text observes text changes via textViewDidChange. Unfortunately, when text changes due to iOS autocorrect, the textViewDidChange is not called, therefore rx_text never receives that new text.

You can test it by creating a text view, make sure autocorrection is enabled, observe rx_text, type a misspelled word and move focus away from the text view. The text will be automatically corrected, but the last change will never be observed via rx_text, because textViewDidChange doesn't fire when autocorrect happens.

@kzaher
Copy link
Member

kzaher commented Dec 12, 2015

Hi @timojaask ,

I've confirmed the problem. This is the only way I know how to solve this, but I don't like it.

e14ca2e

Any ideas how to solve this more elegantly?

@kzaher kzaher added the bug label Dec 17, 2015
@sergdort
Copy link
Contributor

Hi, guys
@kzaher how about rx_observeWeakly of text keypath

@kzaher
Copy link
Member

kzaher commented Dec 23, 2015

Hi @sergdort ,

that's an interesting idea :) I've just tried it, and unfortunately it doesn't seem to work either :/

Also NSNotificationCenter.defaultCenter().rx_notification(UITextViewTextDidChangeNotification, object:self) doesn't fire in that case.

Is there some obvious API I'm missing?

@sergdort
Copy link
Contributor

Just looked at how ReactiveCocoa did this, looks like they did the same and probable they also have bug =)

@kzaher
Copy link
Member

kzaher commented Dec 23, 2015

Haha, yeah, I've also checked other reactive/binding frameworks :)

This hack is the best thing I could conjure so far. ¯_(ツ)_/¯
This does look like a bug in UITextView, but this is a pretty ugly one and would like to find some workaround.

@sergdort
Copy link
Contributor

How about observe textViewDidEndEditing instead of func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool

Looks like this bug appears only when you moving focus away from the text view

@kzaher
Copy link
Member

kzaher commented Dec 23, 2015

Yeah, that also appears to be working ...

I'm wondering is there any other edge case like this one what textViewDidEndEditing: can't catch ...

Maybe we can use textViewDidEndEditing: and I can just implement @objc public func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { return true } so that if we need this uglier hack in future, we don't touch public interface ...

@sergdort
Copy link
Contributor

Looks like this bug could also appears on UITextField rx_text

@sergdort
Copy link
Contributor

There is also NSTextStorageDelegate in textStorage of UITextView
and probably method:

- (void)textStorage:(NSTextStorage *)textStorage didProcessEditing(NSTextStorageEditActions)editedMask range:(NSRange)editedRange changeInLength:(NSInteger)delta

could work too

@kzaher
Copy link
Member

kzaher commented Dec 24, 2015

I have noticed that same behavior on UITextField also. I've also been able to repro this without ending editing :(

I think it's worth a shot to try

- (void)textStorage:(NSTextStorage *)textStorage didProcessEditing(NSTextStorageEditActions)editedMask range:(NSRange)editedRange changeInLength:(NSInteger)delta

... for NSTextView.

I'm still unsure how to solve NSTextField without equivalent ugly hack :/

@sergdort
Copy link
Contributor

Hi @kzaher
Have you tried to add proxy target for UIControlEvents UIControlEvents.AllEditingEvents ?

With this setup
self.textField.addTarget(self, action: "textFieldDidChange:", forControlEvents: .AllEditingEvents)

I was able to get all changes of text

sergdort pushed a commit to sergdort/RxSwift that referenced this issue Dec 26, 2015
kzaher added a commit that referenced this issue Dec 28, 2015
Fixes regarding UITextField rx_text autocorrection bug #333
sergdort pushed a commit to sergdort/RxSwift that referenced this issue Dec 30, 2015
@sergdort
Copy link
Contributor

Hi @kzaher looks like NSTextStorageDelegate works great, please take a look, may be I did something wrong :)

sergdort added a commit to sergdort/RxSwift that referenced this issue Dec 31, 2015
kzaher added a commit that referenced this issue Jan 1, 2016
Fixes for UITextView rx_text bug with autocorrect enabled #333
@kzaher
Copy link
Member

kzaher commented Jan 2, 2016

This is done :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants