react-native-keyboard-controller icon indicating copy to clipboard operation
react-native-keyboard-controller copied to clipboard

Scroll stuttering in multiline TextInputs when growing input height

Open NyoriK opened this issue 1 year ago • 1 comments

Describe the bug Both Android and iOS experience scroll stuttering when multiline TextInputs need to grow, though the behavior differs in severity. This was discovered while investigating #708.

Android:

  • Severe stuttering due to asynchronous layout updates (while investigating #708 by @kirillzyusko )
  • Uses internal scrolling before growing the input
  • Particularly noticeable when:
  1. Typing reaches end of line
  2. Directly pressing enter for new line

Sutters when the cursor reach end of the line and goes to the next line (video):

https://github.com/user-attachments/assets/448fa806-a65d-420a-bc0e-1b31a8437da6

Extreme stutter when pressed enter to go the next line (video):

https://github.com/user-attachments/assets/b96d7ca6-6a38-443e-82ae-81d3352a076d

iOS:

  • Smooth transition when typing reaches end of line and goes to the next line.
  • Slight but noticeable stutter when directly pressing enter for new line
  • Better overall experience compared to Android

Smooth transition when the cursor reach the end of the line and goes to the next line (video):

https://github.com/user-attachments/assets/94694ec7-e560-4181-813b-197c9a83825f

Stutters when pressed enter to go to the next line (video):

https://github.com/user-attachments/assets/cacee5de-4980-4724-9765-2129b02a96ea

The input component should grow immediately and move the cursor smoothly on both platforms, as seen in other mobile app's text inputs.

Code snippet

export default function Index() {
  const n = 5
  const [values, setValues] = useState(Array(n).fill(''))

  const handleChange = (index: number, value: string) => {
    setValues((prev) => {
      const next = [...prev]
      next[index] = value
      return next
    })
  }

  return (
    <View
      style={{
        flex: 1,
        backgroundColor: '#E9E9E9',
      }}
    >
      <KeyboardAwareScrollView
        bottomOffset={50}
        style={styles.container}
        contentContainerStyle={styles.content}
      >
        {
          Array.from({ length: n }).map((_, i) => (
            <View key={i}>
              <Text style={styles.label}>Label {i + 1}</Text>
              <TextInput
                key={i}
                value={values[i]}
                onChangeText={(value) => handleChange(i, value)}
                style={styles.input}
                placeholder={`Enter value ${i + 1}`}
                placeholderTextColor={'#ccc'}
                multiline
              />
            </View>
          ))
        }
      </KeyboardAwareScrollView>
    </View>
  );
}

Repo for reproducing Test project: https://github.com/NyoriK/keyboard-controller-stutter

To Reproduce Steps to reproduce the behavior:

  1. Run the test project
  2. Type text in any multiline TextInput until reaching end of line OR press enter to go to new line
  3. Observe the stuttering scroll behavior as input grows and cursor moves
  4. Compare with iOS which has much smooth transition to the next line.

Expected behavior Input should grow immediately when reaching end of line or pressing enter, with cursor moving smoothly to next line, without internal scrolling or stuttering.

Devices tested: Android:

  • Physical: Redmi Note 10 Pro
  • Emulator: Pixel_8_API_35

iOS:

  • Physical: iPhone 15

Development Environment:

  • Desktop OS: MacOS Sonoma

Additional context

  • React Native Architecture: New Architecture (Fabric)

Environment:

{
  "expo": "~52.0.23",
  "react": "18.3.1",
  "react-native": "0.76.5",
  "react-native-keyboard-controller": "^1.15.2",
  "react-native-reanimated": "~3.16.1"
}

NyoriK avatar Dec 27 '24 17:12 NyoriK

I am getting the exact same issue. Is there a fix or temporary solution for this?

"expo": "^52.0.27", "react": "18.3.1", "react-native": "0.76.6", "react-native-keyboard-controller": "1.15.2", "react-native-reanimated": "3.16.7",

davram88 avatar Feb 02 '25 21:02 davram88