Skip to content

Commit

Permalink
Fix TextInput stack overflow when pasting text in multiline input wit…
Browse files Browse the repository at this point in the history
…h maxlength

Summary: When pasting text longer than maxlenght, the textDidChange: call we did would end calling back into textView:shouldChange: because we saw an unexpected multi-character change. Since this is an expected mutation, update predictedText appropriately.

Reviewed By: majak

Differential Revision: D3561524

fbshipit-source-id: 07bb78d830ccfa3aed6ee274dc30adeadce9e1f8
  • Loading branch information
javache authored and Facebook Github Bot 1 committed Jul 14, 2016
1 parent 55fb4f4 commit 23e087f
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Examples/UIExplorer/js/TextInputExample.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,12 @@ exports.examples = [
keyboardType="url"
style={[styles.multiline, styles.multilineWithFontStyles]}
/>
<TextInput
placeholder="multiline text input with max length"
maxLength={5}
multiline={true}
style={styles.multiline}
/>
<TextInput
placeholder="uneditable multiline text input"
editable={false}
Expand Down
4 changes: 4 additions & 0 deletions Libraries/Text/RCTTextView.m
Original file line number Diff line number Diff line change
Expand Up @@ -377,16 +377,20 @@ - (BOOL)textView:(RCTUITextView *)textView shouldChangeTextInRange:(NSRange)rang
if (_maxLength) {
NSUInteger allowedLength = _maxLength.integerValue - textView.text.length + range.length;
if (text.length > allowedLength) {
// If we typed/pasted more than one character, limit the text inputted
if (text.length > 1) {
// Truncate the input string so the result is exactly maxLength
NSString *limitedString = [text substringToIndex:allowedLength];
NSMutableString *newString = textView.text.mutableCopy;
[newString replaceCharactersInRange:range withString:limitedString];
textView.text = newString;
_predictedText = newString;

// Collapse selection at end of insert to match normal paste behavior
UITextPosition *insertEnd = [textView positionFromPosition:textView.beginningOfDocument
offset:(range.location + allowedLength)];
textView.selectedTextRange = [textView textRangeFromPosition:insertEnd toPosition:insertEnd];

[self textViewDidChange:textView];
}
return NO;
Expand Down

0 comments on commit 23e087f

Please sign in to comment.