From d910768a331a9c290ace577a2acc2b8ba535af49 Mon Sep 17 00:00:00 2001 From: Liu Yongsheng Date: Fri, 30 Nov 2018 11:27:04 +0800 Subject: [PATCH] Fix TextInput maxLength cuts Unicode characters (Emojis) #10964 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: 1. When maxLength is set on TextInput, and allowedLength is 1, when the user picks an emoji character which length is 2 (or 3, 4), then maxLegnth will call `[@"😁" substringToIndex:1]` which will result in clearing all text already input (issue #10929 [iOS][TextInput] emoji after a new line make the line disappear). 2. Fix for this is to check the existence of emoji characters(NSStringEnumerationByComposedCharacterSequences)and shrink allowedLength, ensure that emoji character was rejected as an unit. --- Libraries/Text/TextInput/RCTBaseTextInputView.m | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 21af44009184f1..71b2e129ce0628 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -295,11 +295,20 @@ - (BOOL)textInputShouldChangeTextInRange:(NSRange)range replacementText:(NSStrin } if (_maxLength) { - NSUInteger allowedLength = _maxLength.integerValue - backedTextInputView.attributedText.string.length + range.length; + __block NSUInteger allowedLength = _maxLength.integerValue - backedTextInputView.attributedText.string.length + range.length; if (text.length > allowedLength) { // If we typed/pasted more than one character, limit the text inputted. if (text.length > 1) { + // Fix TextInput maxlength cuts Unicode caracters (Emojis) #10964 + [text enumerateSubstringsInRange:NSMakeRange(0, text.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop){ + // ensure emoji character was not cut + if(substringRange.location + substring.length > allowedLength){ + *stop = true; + allowedLength = substringRange.location; + } + }]; + // Truncate the input string so the result is exactly maxLength NSString *limitedString = [text substringToIndex:allowedLength]; NSMutableAttributedString *newAttributedText = [backedTextInputView.attributedText mutableCopy];