Skip to content

Commit 1f7b0b3

Browse files
sammy-SCgrabbou
authored andcommitted
Calling Paper TextInput setTextAndSelection view command now dirties layout
Summary: Changelog: [Internal] Previously `setTextAndSelection` was not dirtying layout. This would cause an issue where `setTextAndSelection` causes layout change. For example calling setTextAndSelection with empty string on a multiline auto expanding text input. I changed one example in TextInputSharedExamples.js, "Live Re-Write (no spaces allowed) and clear" example is now multiline. This allows to test whether `setTextAndSelection` dirties layout. Enter multiline string to to the example text input and press clear. Observe that the text input shrinks to single line height. Reviewed By: shergin Differential Revision: D21182990 fbshipit-source-id: de8501ea0b97012cf4cdf8d5f658649139f92da6
1 parent 42658cf commit 1f7b0b3

File tree

4 files changed

+22
-18
lines changed

4 files changed

+22
-18
lines changed

Libraries/Text/TextInput/RCTBaseTextInputView.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ NS_ASSUME_NONNULL_BEGIN
4040
@property (nonatomic, copy, nullable) RCTDirectEventBlock onScroll;
4141

4242
@property (nonatomic, assign) NSInteger mostRecentEventCount;
43+
@property (nonatomic, assign, readonly) NSInteger nativeEventCount;
4344
@property (nonatomic, assign) BOOL autoFocus;
4445
@property (nonatomic, assign) BOOL blurOnSubmit;
4546
@property (nonatomic, assign) BOOL selectTextOnFocus;
@@ -51,9 +52,11 @@ NS_ASSUME_NONNULL_BEGIN
5152
@property (nonatomic, copy) NSString *inputAccessoryViewID;
5253
@property (nonatomic, assign) UIKeyboardType keyboardType;
5354

54-
- (void)setText:(NSString *__nullable)text
55-
selectionStart:(NSInteger)start
56-
selectionEnd:(NSInteger)end;
55+
/**
56+
Sets selection intext input if both start and end are within range of the text input.
57+
**/
58+
- (void)setSelectionStart:(NSInteger)start
59+
selectionEnd:(NSInteger)end;
5760

5861
@end
5962

Libraries/Text/TextInput/RCTBaseTextInputView.m

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ @implementation RCTBaseTextInputView {
2424
__weak RCTEventDispatcher *_eventDispatcher;
2525
BOOL _hasInputAccesoryView;
2626
NSString *_Nullable _predictedText;
27-
NSInteger _nativeEventCount;
2827
BOOL _didMoveToWindow;
2928
}
3029

@@ -199,17 +198,9 @@ - (void)setSelection:(RCTTextSelection *)selection
199198
}
200199
}
201200

202-
- (void)setText:(NSString *__nullable)text
203-
selectionStart:(NSInteger)start
204-
selectionEnd:(NSInteger)end
201+
- (void)setSelectionStart:(NSInteger)start
202+
selectionEnd:(NSInteger)end
205203
{
206-
if (text) {
207-
NSMutableAttributedString *mutableString =
208-
[[NSMutableAttributedString alloc] initWithAttributedString:self.backedTextInputView.attributedText];
209-
[mutableString replaceCharactersInRange:NSMakeRange(0, mutableString.string.length) withString:text];
210-
self.backedTextInputView.attributedText = mutableString;
211-
}
212-
213204
UITextPosition *startPosition = [self.backedTextInputView positionFromPosition:self.backedTextInputView.beginningOfDocument
214205
offset:start];
215206
UITextPosition *endPosition = [self.backedTextInputView positionFromPosition:self.backedTextInputView.beginningOfDocument

Libraries/Text/TextInput/RCTBaseTextInputViewManager.m

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,18 @@ - (void)setBridge:(RCTBridge *)bridge
133133
{
134134
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
135135
RCTBaseTextInputView *view = (RCTBaseTextInputView *)viewRegistry[viewTag];
136-
view.mostRecentEventCount = mostRecentEventCount;
137-
[view setText:value selectionStart:start selectionEnd:end];
136+
NSInteger eventLag = view.nativeEventCount - mostRecentEventCount;
137+
if (eventLag != 0) {
138+
return;
139+
}
140+
RCTExecuteOnUIManagerQueue(^{
141+
RCTBaseTextInputShadowView *shadowView = (RCTBaseTextInputShadowView *)[self.bridge.uiManager shadowViewForReactTag:viewTag];
142+
[shadowView setText:value];
143+
[self.bridge.uiManager setNeedsLayout];
144+
RCTExecuteOnMainQueue(^{
145+
[view setSelectionStart:start selectionEnd:end];
146+
});
147+
});
138148
}];
139149
}
140150

RNTester/js/examples/TextInput/TextInputSharedExamples.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,9 @@ class RewriteInvalidCharactersAndClearExample extends React.Component<
161161
ref={ref => {
162162
this.inputRef = ref;
163163
}}
164-
multiline={false}
164+
multiline={true}
165165
onChangeText={text => {
166-
this.setState({text: text.replace(/\s/g, '')});
166+
this.setState({text: text.replace(/ /g, '')});
167167
}}
168168
style={styles.default}
169169
value={this.state.text}

0 commit comments

Comments
 (0)