Skip to content

Commit b0e39b2

Browse files
sammy-SCfacebook-github-bot
authored andcommitted
Maintain cursor position when text changes in text input
Summary: Changelog: [internal] Cursor position needs to be calculated when attributed string changes. Reviewed By: JoshuaGross Differential Revision: D29786190 fbshipit-source-id: 99a42dc4d7c84e77c40f75bf4a9108d010bb1792
1 parent a8e0438 commit b0e39b2

File tree

1 file changed

+12
-7
lines changed

1 file changed

+12
-7
lines changed

React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -528,16 +528,21 @@ - (void)_updateState
528528

529529
- (void)_setAttributedString:(NSAttributedString *)attributedString
530530
{
531-
UITextRange *selectedRange = [_backedTextInputView selectedTextRange];
531+
UITextRange *selectedRange = _backedTextInputView.selectedTextRange;
532+
NSInteger oldTextLength = _backedTextInputView.attributedText.string.length;
532533
if (![self _textOf:attributedString equals:_backedTextInputView.attributedText]) {
533534
_backedTextInputView.attributedText = attributedString;
534535
}
535-
if (_lastStringStateWasUpdatedWith.length == attributedString.length) {
536-
// Calling `[_backedTextInputView setAttributedText]` moves caret
537-
// to the end of text input field. This cancels any selection as well
538-
// as position in the text input field. In case the length of string
539-
// doesn't change, selection and caret position is maintained.
540-
[_backedTextInputView setSelectedTextRange:selectedRange notifyDelegate:NO];
536+
if (selectedRange.empty) {
537+
// Maintaining a cursor position relative to the end of the old text.
538+
NSInteger offsetStart = [_backedTextInputView offsetFromPosition:_backedTextInputView.beginningOfDocument
539+
toPosition:selectedRange.start];
540+
NSInteger offsetFromEnd = oldTextLength - offsetStart;
541+
NSInteger newOffset = attributedString.string.length - offsetFromEnd;
542+
UITextPosition *position = [_backedTextInputView positionFromPosition:_backedTextInputView.beginningOfDocument
543+
offset:newOffset];
544+
[_backedTextInputView setSelectedTextRange:[_backedTextInputView textRangeFromPosition:position toPosition:position]
545+
notifyDelegate:YES];
541546
}
542547
_lastStringStateWasUpdatedWith = attributedString;
543548
}

0 commit comments

Comments
 (0)