Skip to content

Commit

Permalink
fix: don't update text input text directly in setTextAndSelection
Browse files Browse the repository at this point in the history
  • Loading branch information
hannojg committed Oct 11, 2024
1 parent 2c45675 commit 0aa017d
Showing 1 changed file with 16 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -482,19 +482,20 @@ - (void)setTextAndSelection:(NSInteger)eventCount
if (value && ![value isEqualToString:_backedTextInputView.attributedText.string]) {
NSAttributedString *attributedString =
[[NSAttributedString alloc] initWithString:value attributes:_backedTextInputView.defaultTextAttributes];
[self _setAttributedString:attributedString];
[self _updateState];
[self _updateStateWithString:attributedString];
}

UITextPosition *startPosition = [_backedTextInputView positionFromPosition:_backedTextInputView.beginningOfDocument
offset:start];
UITextPosition *endPosition = [_backedTextInputView positionFromPosition:_backedTextInputView.beginningOfDocument
offset:end];

if (startPosition && endPosition) {
UITextRange *range = [_backedTextInputView textRangeFromPosition:startPosition toPosition:endPosition];
// _updateStateWithString executes any state updates sync, so its safe to update the selection as the attributedString is already updated!
[_backedTextInputView setSelectedTextRange:range notifyDelegate:NO];
}

_comingFromJS = NO;
}

Expand Down Expand Up @@ -614,17 +615,27 @@ - (void)handleInputAccessoryDoneButton
}

- (void)_updateState
{
NSAttributedString *attributedString = _backedTextInputView.attributedText;
[self _updateStateWithString:attributedString];
}

- (void)_updateStateWithString:(NSAttributedString*)attributedString
{
if (!_state) {
return;
}
NSAttributedString *attributedString = _backedTextInputView.attributedText;
auto data = _state->getData();
_lastStringStateWasUpdatedWith = attributedString;
data.attributedStringBox = RCTAttributedStringBoxFromNSAttributedString(attributedString);
_mostRecentEventCount += _comingFromJS ? 0 : 1;
data.mostRecentEventCount = _mostRecentEventCount;
_state->updateState(std::move(data));
const auto &textInputEventEmitter = static_cast<const TextInputEventEmitter &>(*_eventEmitter);
// When the textInputDidChange gets called, the text is already updated
// in the UI. We execute the state update synchronously so that the layout gets calculated immediately.
textInputEventEmitter.experimental_flushSync([state = _state, data = std::move(data)]() mutable {
state->updateState(std::move(data));
});
}

- (AttributedString::Range)_selectionRange
Expand Down

0 comments on commit 0aa017d

Please sign in to comment.