mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Maintain selection and cursor location when setting string on TextInput
Summary: Changelog: [Internal] Calling `_backedTextInputView.attributedText = attributedString` causes cursor to be moved to the end of text input. This applies to both, `UITextField` and `UITextView`. This is not desired as when JS sets a new text, we don't want the cursor to be moved to the end of text input. JS has the option to use view commands if it wishes to move cursor somewhere. Reviewed By: JoshuaGross Differential Revision: D20836201 fbshipit-source-id: 9234e54cfbc5fc206f723626988e505275788aae
This commit is contained in:
committed by
Facebook GitHub Bot
parent
7b4889937c
commit
0ef63d0cac
@@ -183,7 +183,7 @@ using namespace facebook::react;
|
||||
if (_state->getRevision() != _stateRevision) {
|
||||
auto data = _state->getData();
|
||||
_stateRevision = _state->getRevision();
|
||||
_backedTextInputView.attributedText = RCTNSAttributedStringFromAttributedStringBox(data.attributedStringBox);
|
||||
[self _setAttributedString:RCTNSAttributedStringFromAttributedStringBox(data.attributedStringBox)];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,6 +198,25 @@ using namespace facebook::react;
|
||||
RCTUIEdgeInsetsFromEdgeInsets(layoutMetrics.contentInsets - layoutMetrics.borderWidth);
|
||||
}
|
||||
|
||||
- (void)_setAttributedString:(NSAttributedString *)attributedString
|
||||
{
|
||||
UITextRange *selectedRange = [_backedTextInputView selectedTextRange];
|
||||
_backedTextInputView.attributedText = attributedString;
|
||||
// Calling `[_backedTextInputView setAttributedText]` results
|
||||
// in `textInputDidChangeSelection` being called but not `textInputDidChange`.
|
||||
// For `_ignoreNextTextInputCall` to have correct value, these calls
|
||||
// need to be balanced, that's why we manually set the flag here.
|
||||
_ignoreNextTextInputCall = NO;
|
||||
if (_lastStringStateWasUpdatedWith.length == attributedString.length) {
|
||||
// Calling `[_backedTextInputView setAttributedText]` moves caret
|
||||
// to the end of text input field. This cancels any selection as well
|
||||
// as position in the text input field. In case the length of string
|
||||
// doesn't change, selection and caret position is maintained.
|
||||
[_backedTextInputView setSelectedTextRange:selectedRange notifyDelegate:NO];
|
||||
}
|
||||
_lastStringStateWasUpdatedWith = attributedString;
|
||||
}
|
||||
|
||||
- (void)prepareForRecycle
|
||||
{
|
||||
[super prepareForRecycle];
|
||||
@@ -406,7 +425,7 @@ using namespace facebook::react;
|
||||
[[NSMutableAttributedString alloc] initWithAttributedString:_backedTextInputView.attributedText];
|
||||
[mutableString replaceCharactersInRange:NSMakeRange(0, _backedTextInputView.attributedText.length)
|
||||
withString:value];
|
||||
_backedTextInputView.attributedText = mutableString;
|
||||
[self _setAttributedString:mutableString];
|
||||
[self _updateState];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user