Skip to content

Commit e788ce8

Browse files
mandriginfacebook-github-bot
authored andcommitted
Apply the fix for CJK languages on single-line text fields. (facebook#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
1 parent 21b8542 commit e788ce8

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

Libraries/Text/TextInput/Singleline/RCTUITextField.m

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
@implementation RCTUITextField {
1616
RCTBackedTextFieldDelegateAdapter *_textInputDelegateAdapter;
17+
NSMutableAttributedString *_attributesHolder;
1718
}
1819

1920
- (instancetype)initWithFrame:(CGRect)frame
@@ -25,6 +26,7 @@ - (instancetype)initWithFrame:(CGRect)frame
2526
object:self];
2627

2728
_textInputDelegateAdapter = [[RCTBackedTextFieldDelegateAdapter alloc] initWithTextField:self];
29+
_attributesHolder = [[NSMutableAttributedString alloc] init];
2830
}
2931

3032
return self;
@@ -107,6 +109,49 @@ - (CGRect)caretRectForPosition:(UITextPosition *)position
107109
return [super caretRectForPosition:position];
108110
}
109111

112+
#pragma mark - Fix for CJK Languages
113+
114+
/*
115+
* The workaround to fix inputting complex locales (like CJK languages).
116+
* When we use `setAttrbutedText:` while user is inputting text in a complex
117+
* locale (like Chinese, Japanese or Korean), some internal state breaks and
118+
* input stops working.
119+
*
120+
* To workaround that, we don't skip underlying attributedString in the text
121+
* field if only attributes were changed. We keep track of these attributes in
122+
* a local variable.
123+
*
124+
* There are two methods that are altered by this workaround:
125+
*
126+
* (1) `-setAttributedText:`
127+
* Applies the attributed string change to a local variable `_attributesHolder` instead of calling `-[super setAttributedText:]`.
128+
* If new attributed text differs from the existing one only in attributes,
129+
* skips `-[super setAttributedText:`] completely.
130+
*
131+
* (2) `-attributedText`
132+
* Return `_attributesHolder` context.
133+
* Updates `_atributesHolder` before returning if the underlying `super.attributedText.string` was changed.
134+
*
135+
*/
136+
- (void)setAttributedText:(NSAttributedString *)attributedText
137+
{
138+
BOOL textWasChanged = ![_attributesHolder.string isEqualToString:attributedText.string];
139+
[_attributesHolder setAttributedString:attributedText];
140+
141+
if (textWasChanged) {
142+
[super setAttributedText:attributedText];
143+
}
144+
}
145+
146+
- (NSAttributedString *)attributedText
147+
{
148+
if (![super.attributedText.string isEqualToString:_attributesHolder.string]) {
149+
[_attributesHolder setAttributedString:super.attributedText];
150+
}
151+
152+
return _attributesHolder;
153+
}
154+
110155
#pragma mark - Positioning Overrides
111156

112157
- (CGRect)textRectForBounds:(CGRect)bounds

0 commit comments

Comments
 (0)