-
Notifications
You must be signed in to change notification settings - Fork 24.4k
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
[iOS][TextInput] Apply the fix for CJK languages on single-line text fields. #22546
Conversation
f2ee775
to
ad7bd64
Compare
a0a1f1c
to
bc35574
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't we move all this logic inside -[RCTUITextView setAttributedText]
(which might imply adding sanitizing inside the getter. And same thing for UITextField
subclass.
There is a huge reason for that desire: This module is the most complex module in the whole RN rendering subsystem. We have to push all logic that might be considered as "improvements of core UIKit components" down to subclasses dedicated for that. The reason is that our RN-specific model of the world implies that our expectations about how UIKit works are correct. That's really challenging to implement the ideal modal itself, so we cannot afford polluting that with UIKit specific fixes. We have to decouple them in subclasses that "fix" UIKit stuff for us.
@mandrigin I deeply appreciate your effort and I am existed about those fixes. We struggled with them for so long time! But we really need to do it right to make it sustainable. |
[_attributesHolder setAttributedString:super.attributedText]; | ||
} | ||
|
||
- (NSAttributedString *)attributedText { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shergin it is easier to me to comment here, to show why I did it this way.
UITextField
is a very basic UI element. It doesn't expose any API to just change the string attributes without re-setting the attributed string completely (and breaking CJK input).
Luckily, it relies on it's own public (and overridable) property attributedText
when rendering.
What I'm doing here is hijacking this property and replacing its value with the value I store locally, in NSMutableAttributedString, which I can replace without noticeable side-effects. So this override has to be here, if we want to continue to use UITextField. It's a hack and it can potentially break with new iOS releases, etc.
To be able to consolidate logic, we can just use UITextView everywhere, it provides all the necessary functionality as public APIs. What is the history between having 2 different implementations for single and multiline text views?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean why not consolidate all attribute specific-logic in this class making attributedText
and setAttributedText
behave as we want?
We have to have two different underlying components because they simply behave differently. There is no way to configure UITextView behave exactly as UITextField.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean we have an original problem: When we call setAttributedText
, marked fragment gets reset. So, let's add all checks that prevents that into both RCTUITextField
and RCTUITextView
(iirc, now we have only one of them).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, okay, I mistread your initial comment.
So you mean, just duplicate the logic and encapsulate it inside RCTUITextField
and RCTUITextView
classes separately, so we can call setAttributedString
safely on both RCTUITextField
and RCTUITextView
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be fixed now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Let's continue discussion here.)
Now we are abstracted from anything else, so we can work on it. 😄
I think, it's great. ❤️
Nits:
- Instead of referring issues and commenting every single line, we have to leave one comment that describe a problem and (most importantly) the change in the behavior of the methods. That's more sustainable and easy to understand for people from the future which don't have a full context.
- Codestyle. (New line before
{
and spaces.)
Btw, I don't think it's only fix for CJK problem. It's more wide problem which happens when we are replacing some attributed string with completely new one without paying attention to what attributes were added to the string by active text input. So, if we can preserve those attributes, I bet full replacing will work with CJK. (The current solution is good enough though.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pushed the fix to address this feedback
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shergin is there anything else I need to fix in this PR?
// Search for `GH-19339` to see all code affected by this fix. | ||
|
||
- (void)setAttributedText:(NSAttributedString *)attributedText { | ||
[_attributesHolder setAttributedString:attributedText]; |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
bc35574
to
5592d66
Compare
@shergin I just simplified my fix to affect only one source file. |
5592d66
to
b67f2c7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shergin is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
…#22546) Summary: Follow-up to facebook#19809 This fix generalizes the `setAttributedString:` fix to single-line text fields. Fixes facebook#19339 _Pull requests that expand test coverage are more likely to get reviewed. Add a test case whenever possible!_ Pull Request resolved: facebook#22546 Differential Revision: D13948951 Pulled By: shergin fbshipit-source-id: 67992c02b32f33f6d61fac4554e4f46b973262c1
I'm going to have to revert this, it broke single line text inputs, sorry 😥 Repro: |
Sure, I will take a look next week on what can be improved |
…est fields. Summary: This PR (#22546) broke single line text inputs. After inputting some text and tapping away, the text input reverts back to default text. Revert solved the issue. Reviewed By: cpojer Differential Revision: D14185897 fbshipit-source-id: cc7f0f2ebfb0494062afbc628c4fe27ad27fb1c6
By the way, this issue repros on iOS 9 and iOS 10 only. @mandrigin were you able to make any progress on this? I'm interested in a fix for a related issue where the keyboard doesn't automatically switch back from numbers to letters on typing space. |
@alsun2001 sorry, was a bit busy at first and then I was on vacation. I'm back, I'll take a look at it this week. Knowing that that is iOS 9 and iOS 10 issue only helps a lot, thanks! |
…est fields. Summary: This PR (#22546) broke single line text inputs. After inputting some text and tapping away, the text input reverts back to default text. Revert solved the issue. Reviewed By: cpojer Differential Revision: D14185897 fbshipit-source-id: cc7f0f2ebfb0494062afbc628c4fe27ad27fb1c6
@PeteTheHeat @alsun2001 I can't reproduce the original (CJK input) issue in 0.59.3. |
There have been quite a few small changes to text inputs recently, so I wouldn't be surprised if it was fixed. Thanks for following up with this!! |
Summary: <!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? --> Fix #32503 Updating the attributed text in TextView/TextField while inputting Korean language will break input mechanism of the Korean alphabet. This results unexpected text input. This PR supersedes the previous fixes: #19809, #22546 ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> [iOS] [Fixed] - Fix a broken input for the Korean alphabet in TextInput Pull Request resolved: #32523 Test Plan: https://user-images.githubusercontent.com/20317121/140013434-1674c391-54d6-4410-b4c1-c633697e639d.mov Reviewed By: lunaleaps, sammy-SC Differential Revision: D32470543 Pulled By: philIip fbshipit-source-id: e7e34bd362fa2ab2ca579103db01ad8d1a891c35
Summary: <!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? --> Fix #32503 Updating the attributed text in TextView/TextField while inputting Korean language will break input mechanism of the Korean alphabet. This results unexpected text input. This PR supersedes the previous fixes: #19809, #22546 ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> [iOS] [Fixed] - Fix a broken input for the Korean alphabet in TextInput Pull Request resolved: #32523 Test Plan: https://user-images.githubusercontent.com/20317121/140013434-1674c391-54d6-4410-b4c1-c633697e639d.mov Reviewed By: lunaleaps, sammy-SC Differential Revision: D32470543 Pulled By: philIip fbshipit-source-id: e7e34bd362fa2ab2ca579103db01ad8d1a891c35
Summary: <!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? --> Fix #32503 Updating the attributed text in TextView/TextField while inputting Korean language will break input mechanism of the Korean alphabet. This results unexpected text input. This PR supersedes the previous fixes: #19809, #22546 ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> [iOS] [Fixed] - Fix a broken input for the Korean alphabet in TextInput Pull Request resolved: #32523 Test Plan: https://user-images.githubusercontent.com/20317121/140013434-1674c391-54d6-4410-b4c1-c633697e639d.mov Reviewed By: lunaleaps, sammy-SC Differential Revision: D32470543 Pulled By: philIip fbshipit-source-id: e7e34bd362fa2ab2ca579103db01ad8d1a891c35
Follow-up to #19809
This fix generalizes the
setAttributedString:
fix to single-line text fields.Fixes #19339
Pull requests that expand test coverage are more likely to get reviewed. Add a test case whenever possible!
Test Plan:
The test app
Essentially, the steps to reproduce are described in the issue:
하늘
" (buttonsㅎ
,ㅏ
,ㄴ
,ㅡ
,ㄹ
).파란
" (buttonsㅍ
,ㅏ
,ㄹ
,ㅏ
,ㄴ
) this time.Behaviour before this fix
Actual text (Single-line):
ㅍㅏㄹㅏㄴ하늘
.Actual text (Multi-line):
파란하늘
.Expected text (both fields):
파란하늘
.Characters aren't combined properly in single-line.
Behaviour after this fix (correct)
Actual text (Single-line):
파란하늘
.Actual text (Multi-line):
파란하늘
.Expected text (both fields):
파란하늘
.Characters are combined correctly.
Changelog:
[IOS] [BUGFIX] [TextView] - Fix Korean/Chinese/Japanese input for single-line TextView on iOS.