@@ -528,16 +528,21 @@ - (void)_updateState
528
528
529
529
- (void )_setAttributedString : (NSAttributedString *)attributedString
530
530
{
531
- UITextRange *selectedRange = [_backedTextInputView selectedTextRange ];
531
+ UITextRange *selectedRange = _backedTextInputView.selectedTextRange ;
532
+ NSInteger oldTextLength = _backedTextInputView.attributedText .string .length ;
532
533
if (![self _textOf: attributedString equals: _backedTextInputView.attributedText]) {
533
534
_backedTextInputView.attributedText = attributedString;
534
535
}
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 ];
541
546
}
542
547
_lastStringStateWasUpdatedWith = attributedString;
543
548
}
0 commit comments