@@ -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