Skip to content

Commit 7771317

Browse files
ouchuanfacebook-github-bot
authored andcommitted
fix(ios): avoid incorrectly updating caret position (#50680)
Summary: Avoid incorrectly updating caret position Pull Request resolved: #50641 The caret position is updated incorrectly when a user is first typing if an zero-length selection is set. ## Changelog: [IOS] [CHANGED] - Typing into TextInput now will not cause the caret position to update to the beginning when a zero-length selection is set. Pull Request resolved: #50680 Test Plan: Tested with the following code(a simplified version from the code in #50641) ```js const [selection, setSelection] = useState({start: -1, end: -1}); const onSelectionChange = ( evt: NativeSyntheticEvent<TextInputSelectionChangeEventData>, ) => { const {selection} = evt.nativeEvent; const {start, end} = selection; console.log('selection change: ', start, end); setSelection(selection); }; return ( <View style={{ position: 'absolute', top: 50, left: 30 }}> <TextInput placeholder="test" selection={selection} onSelectionChange={onSelectionChange} /> </View> ); ``` When using the main branch, the caret position will jump back to the beginning after the first typing. It works fine after applying this commit. Reviewed By: fabriziocucci Differential Revision: D72957245 Pulled By: cipolleschi fbshipit-source-id: 3586797332b35e86b17f386a35e7d192ff758f7e
1 parent db4b3df commit 7771317

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,11 @@ - (void)_updateState
702702
}
703703

704704
- (void)_restoreTextSelection
705+
{
706+
[self _restoreTextSelectionAndIgnoreCaretChange:NO];
707+
}
708+
709+
- (void)_restoreTextSelectionAndIgnoreCaretChange:(BOOL)ignore
705710
{
706711
const auto &selection = static_cast<const TextInputProps &>(*_props).selection;
707712
if (!selection.has_value()) {
@@ -711,6 +716,9 @@ - (void)_restoreTextSelection
711716
offset:selection->start];
712717
auto end = [_backedTextInputView positionFromPosition:_backedTextInputView.beginningOfDocument offset:selection->end];
713718
auto range = [_backedTextInputView textRangeFromPosition:start toPosition:end];
719+
if (ignore && range.empty) {
720+
return;
721+
}
714722
[_backedTextInputView setSelectedTextRange:range notifyDelegate:YES];
715723
}
716724

@@ -736,7 +744,9 @@ - (void)_setAttributedString:(NSAttributedString *)attributedString
736744
notifyDelegate:YES];
737745
[_backedTextInputView scrollRangeToVisible:NSMakeRange(offsetStart, 0)];
738746

739-
[self _restoreTextSelection];
747+
// A zero-length selection range can cause the caret position to change on iOS,
748+
// and we have already updated the caret position, so we can safely ignore caret changing in this place.
749+
[self _restoreTextSelectionAndIgnoreCaretChange:YES];
740750
[self _updateTypingAttributes];
741751
_lastStringStateWasUpdatedWith = attributedString;
742752
}

0 commit comments

Comments
 (0)