react-native
                                
                                 react-native copied to clipboard
                                
                                    react-native copied to clipboard
                            
                            
                            
                        Fix Multiline TextInput with a fixed height scrolls to the bottom when prepending new lines to the text
Summary:
Please re-state the problem that we are trying to solve in this issue.
Multiline TextInput with a fixed height will scroll to the bottom of the screen when prepending new lines to the text.
What is the root cause of that problem?
The issue is caused by iOS UITextView:
- The cursor moves to the end of the text when prepending new lines.
- Moving the cursor to the end of the text triggers the scroll to the bottom.
The behavior was reproduced on an iOS App (without react-native). The example included below implements a Component RCTUITextView based on UITextView, which modifies the UITextView attributedText with the textViewDidChange callback (source code available in this comment).
Adding a new line on top of the UITextView on iOS results in: Issue 1) The cursor moves to the end of TextInput text Issue 2) The TextInput scrolls to the bottom
Reproducing the issue on an iOS App without react-native
Issue 1) is already fixed in react-native, which restores the previous cursor position (on Fabric with _setAttributedString) after changing the text. Issue 2) needs to be fixed in react-native.
What changes do you think we should make in order to solve the problem?
Setting the correct TextInput scroll position after re-setting the cursor.
Changelog:
[IOS] [FIXED] - Fix Multiline TextInput with a fixed height scrolls to the bottom when changing AttributedText
Test Plan:
Fabric (reproduces on controlled/not controlled TextInput example):
| Before | After | 
|---|---|
Paper (reproduces only on controlled TextInput example):
function TextInputExample() {
  const [text, setText] = React.useState('');
  return (
    <View style={{marginTop: 200}}>
      <TextInput
        style={{height: 50, backgroundColor: 'white'}}
        multiline={true}
        value={text}
        onChangeText={text => {
          setText(text);
        }}
      />
    </View>
  );
}
| Before | After | 
|---|---|
| Platform | Engine | Arch | Size (bytes) | Diff | 
|---|---|---|---|---|
| android | hermes | arm64-v8a | 17,885,642 | -1 | 
| android | hermes | armeabi-v7a | n/a | -- | 
| android | hermes | x86 | n/a | -- | 
| android | hermes | x86_64 | n/a | -- | 
| android | jsc | arm64-v8a | 21,240,040 | +1 | 
| android | jsc | armeabi-v7a | n/a | -- | 
| android | jsc | x86 | n/a | -- | 
| android | jsc | x86_64 | n/a | -- | 
Base commit: 475a15631056f03822352f798158aa956b782ddd Branch: main
Would this also prevent scroll when adding to the end of the list?
Thanks for the code review. I moved the PR to draft. I'm working on a solution for this issue.
https://github.com/facebook/react-native/assets/24992535/14811724-8dc7-40f9-824e-713ff14c45df
Thanks for the code-review @NickGerleman. I updated the PR and I included a video test in this comment.
@NickGerleman has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.
Thanks @NickGerleman. Could you tell me what is the lint warning? I can fix it and push again the branch so it is easier to import.
It's a formatting issue that I can fix before landing, but it is waiting on a reviewer of the imported PR. The best expert for iOS TextInput has been out of office.
Thanks, @NickGerleman. Maybe the formatting issue is the maximum line length? I want to push an updated version of this PR to fix the Facebook Internal Linter warning.
Thanks @NickGerleman. I want to help to get this PR merged. I have been away for 2+ months, I had to move to a new home, but now I'm again available to help.
Thanks @NickGerleman. How can I help to get this PR merged?
Looks like this stuck at the Phabricator import. Any chance we can push this forward? :)
Hey @NickGerleman, looks like this one's pretty far in the review and just needs some final touches. Is it possible you can jump in to help here?
Hey there everyone, sorry for the radio silence. I have worked with text before, and tried to give this a look through, but I don't have much familiarity with the iOS text implementation, to be able to say that this is the right solution, in the right place, etc. I just asked someone with more familiarity there to take a look. But otherwise, will take a look at shipping this next week.
Thanks @NickGerleman. I replied to your code-review and further improved the solution as by Meta requirement. https://github.com/facebook/react-native/pull/38679#discussion_r1493960840 https://github.com/facebook/react-native/pull/38679#discussion_r1493960647
Thanks @NickGerleman. I replied to your code-review and further improved the solution as by Meta requirement. #38679 (comment) #38679 (comment)
I will take another look at this soon (still need to write the accompanying internal tests first).
Thanks @NickGerleman. I replied to your code-review and further improved the solution as by Meta requirement. #38679 (comment) #38679 (comment)
I will take another look at this soon (still need to write the accompanying internal tests first).
Finally cleared some other commitments, so writing those tests now.
@NickGerleman has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.
@NickGerleman merged this pull request in facebook/react-native@f6badca2f9a5f1e986dd76444bebde0d6049513d.