Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign up[iOS][TextInput] Apply the fix for CJK languages on single-line text fields. #22546
Conversation
mandrigin
referenced this pull request
Dec 6, 2018
Closed
ReactNative's state update via this.setState breaks text input mode for Korean, Chinese, Japanese characters in 0.54 and 0.55 #19339
react-native-bot
added
🔶 Components
Component: Text
Component: TextInput
Platform: iOS
labels
Dec 6, 2018
facebook-github-bot
added
the
CLA Signed
label
Dec 6, 2018
mandrigin
force-pushed the
mandrigin:fix-cjk-single-line
branch
from
f2ee775
to
ad7bd64
Dec 6, 2018
react-native-bot
added
the
PR: Includes Changelog
label
Dec 6, 2018
cpojer
requested a review
from
shergin
Dec 7, 2018
mandrigin
force-pushed the
mandrigin:fix-cjk-single-line
branch
2 times, most recently
from
a0a1f1c
to
bc35574
Dec 7, 2018
shergin
requested changes
Dec 13, 2018
Why can't we move all this logic inside 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. |
This comment has been minimized.
This comment has been minimized.
@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. |
mandrigin
reviewed
Dec 13, 2018
[_attributesHolder setAttributedString:super.attributedText]; | ||
} | ||
|
||
- (NSAttributedString *)attributedText { |
This comment has been minimized.
This comment has been minimized.
mandrigin
Dec 13, 2018
Author
Contributor
@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?
This comment has been minimized.
This comment has been minimized.
shergin
Dec 13, 2018
Contributor
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.
This comment has been minimized.
This comment has been minimized.
shergin
Dec 13, 2018
•
Contributor
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).
This comment has been minimized.
This comment has been minimized.
mandrigin
Dec 13, 2018
Author
Contributor
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
?
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
shergin
Jan 8, 2019
Contributor
(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.)
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
shergin
reviewed
Dec 13, 2018
// 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.
shergin
Dec 13, 2018
Contributor
I mean why not to fallback to copyAttributesFrom
here, if we see that super.attributedText.string === attributedText
?
This comment was marked as outdated.
This comment was marked as outdated.
mandrigin
force-pushed the
mandrigin:fix-cjk-single-line
branch
from
bc35574
to
5592d66
Dec 17, 2018
This comment has been minimized.
This comment has been minimized.
@shergin I just simplified my fix to affect only one source file. |
mandrigin
force-pushed the
mandrigin:fix-cjk-single-line
branch
from
5592d66
to
b67f2c7
Jan 9, 2019
hramos
removed
the
🔶 Components
label
Jan 24, 2019
facebook-github-bot
added
the
Import Started
label
Feb 4, 2019
facebook-github-bot
approved these changes
Feb 4, 2019
facebook-github-bot left a comment
@shergin is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
mandrigin commentedDec 6, 2018
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.