Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiline TextInput Auto-growing and Scrolling Behavior Issues with KeyboardAwareScrollView #794

Open
NyoriK opened this issue Feb 1, 2025 · 6 comments · May be fixed by #797
Open

Multiline TextInput Auto-growing and Scrolling Behavior Issues with KeyboardAwareScrollView #794

NyoriK opened this issue Feb 1, 2025 · 6 comments · May be fixed by #797
Assignees
Labels
🤖 android Android specific 🍎 iOS iOS specific KeyboardAwareScrollView 📜 Anything related to KeyboardAwareScrollView component

Comments

@NyoriK
Copy link

NyoriK commented Feb 1, 2025

Overview
I've identified several inconsistencies in the TextInput component's auto-growing behavior when used with KeyboardAwareScrollView, affecting both iOS and Android platforms. These issues vary depending on prop configurations and component wrapping.

Detailed Findings

Base Case (No value/onChangeText props)

  • TextInput doesn't auto-grow regardless of multiline prop
  • Height only respects minHeight or height style properties
  • Behavior consistent across iOS and Android
kas-without-props.mp4

With value and onChangeText props

  1. Height Behavior:
  • Respects minHeight and auto-grows after reaching minimum
  • Fixed height when explicitly set; no auto-growing beyond specified height
  1. Scrolling Issues:
  • Noticeable "jumpy" behavior when:

    • Cursor reaches end of last line
    • First character on new line triggers internal scroll
    • Second character triggers height auto-grow and ScrollView adjustment
kas-with-props.mp4
  • Less noticeable when cursor is in middle of content

TextInput Wrapped in View

  • Auto-growing works without value/onChangeText props
  • Platform-specific differences:
    • iOS: Minimal jumping, hardly noticeable
    • Android: Jumping behavior persists, similar to non-wrapped version
kas-with-views.mp4

Comparison with React Native's ScrollView
Native ScrollView demonstrates superior behavior:

  • Consistent auto-growing without requiring value/onChangeText props
  • Significantly reduced jumping compared to KeyboardAwareScrollView with View wrapper
rns-without-props-and-views.mp4

Code Examples
I've included three implementation scenarios to demonstrate these issues and one with react native ScrollView:

  1. Basic Implementation
<KeyboardAwareScrollView>
  <TextInput 
    multiline
    placeholder="TextInput"
    placeholderTextColor="black"
    style={styles.textInput}
  />
</KeyboardAwareScrollView>
  1. With Props
<KeyboardAwareScrollView>
  <TextInput 
    multiline
    value={value}
    onChangeText={onChange}
    placeholder="TextInput"
    placeholderTextColor="black"
    style={styles.textInput}
  />
</KeyboardAwareScrollView>
  1. With View Wrapper
<KeyboardAwareScrollView>
  <View>
  <TextInput 
    multiline
    placeholder="TextInput"
    placeholderTextColor="black"
    style={styles.textInput}
  />
  </View>
</KeyboardAwareScrollView>
  1. React Native ScrollView
<ScrollView>
  <TextInput 
    multiline
    placeholder="TextInput"
    placeholderTextColor="black"
    style={styles.textInput}
  />
</ScrollView>

Devices tested:
Android:

  • Physical: Redmi Note 10 Pro
  • Emulator: Pixel_8_API_35

iOS:

  • Physical: iPhone 15

Development Environment:

  • Desktop OS: MacOS Sonoma

Environment:

  • expo: "~52.0.28"
  • expo: "~52.0.28"
  • react-native: "0.76.6"
  • react-native-keyboard-controller: "^1.16.1"
@kirillzyusko kirillzyusko added KeyboardAwareScrollView 📜 Anything related to KeyboardAwareScrollView component 🤖 android Android specific 🍎 iOS iOS specific labels Feb 1, 2025
@kirillzyusko
Copy link
Owner

@NyoriK do you test new architecture or old?

@NyoriK
Copy link
Author

NyoriK commented Feb 2, 2025

@kirillzyusko Yes.

app.json:

{
    "expo": {
        "name": "multiline-app",
        "slug": "multiline-app",
        "version": "1.0.0",
        "orientation": "portrait",
        "icon": "./assets/images/icon.png",
        "scheme": "myapp",
        "userInterfaceStyle": "automatic",
        "newArchEnabled": true,
        "ios": {
            "supportsTablet": true,
            "bundleIdentifier": "com.knyoridev.multiline-app"
        },
        "android": {
            "adaptiveIcon": {
                "foregroundImage": "./assets/images/adaptive-icon.png",
                "backgroundColor": "#ffffff"
            },
            "package": "com.knyoridev.multilineapp"
        },
        "web": {
            "bundler": "metro",
            "output": "static",
            "favicon": "./assets/images/favicon.png"
        },
        "plugins": [
            "expo-router",
            [
                "expo-splash-screen",
                {
                    "image": "./assets/images/splash-icon.png",
                    "imageWidth": 200,
                    "resizeMode": "contain",
                    "backgroundColor": "#ffffff"
                }
            ]
        ],
        "experiments": {
            "typedRoutes": true
        }
    }
}

@kirillzyusko
Copy link
Owner

@NyoriK would you mind to try this PR? And let me know if it fixes the problem for you?

In general it works, but the main downside is that it doesn't work on Android - I opened a PR in react-native. Let's see if it gets accepted/merged 👀

@kirillzyusko kirillzyusko linked a pull request Feb 3, 2025 that will close this issue
2 tasks
@NyoriK
Copy link
Author

NyoriK commented Feb 4, 2025

@kirillzyusko I've tested the PR, and can confirm it works as intended on iOS.

The behavior is now much closer to native ScrollView. There's still some minor jumpiness when typing at the end of the TextInput, but this appears to be the same as with native ScrollView and is expected due to the combination of TextInput's internal scroll and asynchronous height adjustments (as discussed in #708).

Looking forward to the Android fix once the React Native PR is merged. Thanks for working on this!

@NyoriK NyoriK closed this as completed Feb 4, 2025
@NyoriK
Copy link
Author

NyoriK commented Feb 4, 2025

@kirillzyusko Just tested again on Android and can confirm - the fix doesn't work on Android. When typing reaches the keyboard area, the KeyboardAwareScrollView doesn't scroll up, and the content being typed goes underneath the keyboard. Will await the Android fix once the React Native PR is merged.

@NyoriK NyoriK reopened this Feb 4, 2025
@kirillzyusko
Copy link
Owner

Just tested again on Android and can confirm - the fix doesn't work on Android. When typing reaches the keyboard area, the KeyboardAwareScrollView doesn't scroll up, and the content being typed goes underneath the keyboard. Will await the Android fix once the React Native PR is merged.

Yeah, an intermediate solution can be combining "additional view" approach on Android and using contentInset on iOS.

But it looks like PR has been merged in upstream, so maybe in RN 0.79 we'll get this prop available on Android 🙈

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤖 android Android specific 🍎 iOS iOS specific KeyboardAwareScrollView 📜 Anything related to KeyboardAwareScrollView component
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants