From 82d3519e1b5551d703590b0fb1ec92724133f8e1 Mon Sep 17 00:00:00 2001 From: Minsik Kim Date: Wed, 3 Nov 2021 13:14:33 +0900 Subject: [PATCH 1/4] fall back to bare text comparison when inputting korean --- Libraries/Text/TextInput/RCTBaseTextInputView.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 865a03488d9926..9d90a7395fd802 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -104,6 +104,7 @@ - (BOOL)textOf:(NSAttributedString*)newText equals:(NSAttributedString*)oldText{ // Similarly, when the user is in the middle of inputting some text in Japanese/Chinese, there will be styling on the // text that we should disregard. See https://developer.apple.com/documentation/uikit/uitextinput/1614489-markedtextrange?language=objc // for more info. + // Also, updating the attributed text while inputting Korean language will break input mechanism. // If the user added an emoji, the system adds a font attribute for the emoji and stores the original font in NSOriginalFont. // Lastly, when entering a password, etc., there will be additional styling on the field as the native text view // handles showing the last character for a split second. @@ -116,6 +117,7 @@ - (BOOL)textOf:(NSAttributedString*)newText equals:(NSAttributedString*)oldText{ BOOL shouldFallbackToBareTextComparison = [self.backedTextInputView.textInputMode.primaryLanguage isEqualToString:@"dictation"] || + [self.backedTextInputView.textInputMode.primaryLanguage isEqualToString:@"ko-KR"] || self.backedTextInputView.markedTextRange || self.backedTextInputView.isSecureTextEntry || fontHasBeenUpdatedBySystem; From ea6b9d8cb9a936b5ea4bb0ac24ba3b56e5b1c04e Mon Sep 17 00:00:00 2001 From: Minsik Kim Date: Wed, 3 Nov 2021 13:15:10 +0900 Subject: [PATCH 2/4] remove redundant overrides --- .../Text/TextInput/Multiline/RCTUITextView.m | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index 4a94455025dfd3..794185481b61bf 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -145,26 +145,6 @@ - (void)setTextAlignment:(NSTextAlignment)textAlignment _placeholderView.textAlignment = textAlignment; } -- (void)setAttributedText:(NSAttributedString *)attributedText -{ - // Using `setAttributedString:` while user is typing breaks some internal mechanics - // when entering complex input languages such as Chinese, Korean or Japanese. - // see: https://github.com/facebook/react-native/issues/19339 - - // We try to avoid calling this method as much as we can. - // If the text has changed, there is nothing we can do. - if (![super.attributedText.string isEqualToString:attributedText.string]) { - [super setAttributedText:attributedText]; - } else { - // But if the text is preserved, we just copying the attributes from the source string. - if (![super.attributedText isEqualToAttributedString:attributedText]) { - [self copyTextAttributesFrom:attributedText]; - } - } - - [self textDidChange]; -} - - (void)setSelectedTextRange:(UITextRange *)selectedTextRange notifyDelegate:(BOOL)notifyDelegate { if (!notifyDelegate) { @@ -311,18 +291,4 @@ - (CGRect)caretRectForPosition:(UITextPosition *)position #pragma mark - Utility Methods -- (void)copyTextAttributesFrom:(NSAttributedString *)sourceString -{ - [self.textStorage beginEditing]; - - NSTextStorage *textStorage = self.textStorage; - [sourceString enumerateAttributesInRange:NSMakeRange(0, sourceString.length) - options:NSAttributedStringEnumerationReverse - usingBlock:^(NSDictionary * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) { - [textStorage setAttributes:attrs range:range]; - }]; - - [self.textStorage endEditing]; -} - @end From c679dab8a0254e20067401c687e34d915e787bd4 Mon Sep 17 00:00:00 2001 From: Minsik Kim Date: Wed, 3 Nov 2021 14:29:42 +0900 Subject: [PATCH 3/4] add fabric version --- .../ComponentViews/TextInput/RCTTextInputComponentView.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm index bbe622eebfc163..4e3c5a55476ffb 100644 --- a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm @@ -579,8 +579,9 @@ - (BOOL)_textOf:(NSAttributedString *)newText equals:(NSAttributedString *)oldTe // the settings on a dictation. // Similarly, when the user is in the middle of inputting some text in Japanese/Chinese, there will be styling on the // text that we should disregard. See - // https://developer.apple.com/documentation/uikit/uitextinput/1614489-markedtextrange?language=objc for more info. If - // the user added an emoji, the system adds a font attribute for the emoji and stores the original font in + // https://developer.apple.com/documentation/uikit/uitextinput/1614489-markedtextrange?language=objc for more info. + // Also, updating the attributed text while inputting Korean language will break input mechanism. + // If the user added an emoji, the system adds a font attribute for the emoji and stores the original font in // NSOriginalFont. Lastly, when entering a password, etc., there will be additional styling on the field as the native // text view handles showing the last character for a split second. __block BOOL fontHasBeenUpdatedBySystem = false; @@ -595,6 +596,7 @@ - (BOOL)_textOf:(NSAttributedString *)newText equals:(NSAttributedString *)oldTe BOOL shouldFallbackToBareTextComparison = [_backedTextInputView.textInputMode.primaryLanguage isEqualToString:@"dictation"] || + [_backedTextInputView.textInputMode.primaryLanguage isEqualToString:@"ko-KR"] || _backedTextInputView.markedTextRange || _backedTextInputView.isSecureTextEntry || fontHasBeenUpdatedBySystem; if (shouldFallbackToBareTextComparison) { From 2dd1dc07079ee5f93cccd445cfb7de9557029620 Mon Sep 17 00:00:00 2001 From: Minsik Kim Date: Thu, 18 Nov 2021 18:09:35 +0900 Subject: [PATCH 4/4] invalidate placeholder visibility --- Libraries/Text/TextInput/Multiline/RCTUITextView.m | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index 794185481b61bf..979bdb05c22fc9 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -145,6 +145,12 @@ - (void)setTextAlignment:(NSTextAlignment)textAlignment _placeholderView.textAlignment = textAlignment; } +- (void)setAttributedText:(NSAttributedString *)attributedText +{ + [super setAttributedText:attributedText]; + [self textDidChange]; +} + - (void)setSelectedTextRange:(UITextRange *)selectedTextRange notifyDelegate:(BOOL)notifyDelegate { if (!notifyDelegate) {