KeyboardAvoidingView with ScrollView

I am sort of new to react native and have one question that I did not find in react native documentation.

I am looking into this component KeyboardAvoidingView: https://facebook.github.io/react-native/docs/keyboardavoidingview.html

Question is simple - has anyone to get KeyboardAvoidingView to work nicely with ScrollView? I have many TextInputs in one component (sum of TextInputs height is bigger then device height), and once the keyboard appears, I have various issues..
If I use View instead of ScrollView then everything is fine, but I can't use it, since I need more space than the device height.. I Couldn't find anything about Scroll in the KeyboardAvoidingView documentation.

Thanks.

99370 次浏览

It looks like facebook has not yet implemented a solution for scrollViews. But I have found solution made by Wix, react-native-keyboard-aware-scrollview that works like it should :)

npm i react-native-keyboard-aware-scrollview --save

import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scrollview';


<KeyboardAwareScrollView style={styles.container}>
<TextInput style={styles.textInput} placeholder={'My Input'} />
</KeyboardAwareScrollView>

I also tried to find the solution on the internet, but I figured it out myself. I was able to make keyboardAvoidingView to work with ScrollView on the iPhone SE simulator.

I used padding type position, with keyboardVerticalOffset set to some higher value. I hope this helps everybody who is trapped in this situation.

render() {
return (
<View style={...}>
<ScrollView>
<KeyboardAvoidingView
style=\{\{ flex: 1 }}
keyboardVerticalOffset={100}
behavior={"position"}
>
<TextInput style={styles.editInput} ... />
</KeyboardAvoidingView>
</ScrollView>
</View>
);
}

I ran into the same issue, though I had a different approach that basically will calculate and positioning (using translateY) the view when the keyboard appears.

I have published the solution on github and NPM react-native-spacer.

In my case I used: https://github.com/APSL/react-native-keyboard-aware-scroll-view.

<KeyboardAwareScrollView>
....
<MyContainerComponent>
....
<MyFormComponentWithInputs />
</MyContainerComponent>
</KeyboardAwareScrollView>

It supports older RN versions too.

My text input was somewhere hidden deep is some custom child component of the ScrollView but the package worked great for both Android and iOS

This is what my solution would be, it works and scrolls automatically on focus input. I tried this on Expo, hope it helps.

<KeyboardAvoidingView style=\{\{ flex: 1, flexDirection: 'column',justifyContent: 'center',}} behavior="padding" enabled   keyboardVerticalOffset={100}>
<ScrollView>
<View style={Styles.row}>
//your view
</View>
</ScrollView>
</KeyboardAvoidingView>

I was also facing this issue ,spent more than 4 hours to figure out this issue and lastly find this solution.

<KeyboardAvoidingView style=\{\{ flex: 1, flexDirection: 'column',justifyContent: 'center'}} behavior="position" enabled   keyboardVerticalOffset={200}>
<ScrollView>
<Text style=\{\{padding:10,fontSize:42}}>Text 1</Text>
<Text style=\{\{padding:10,fontSize:42}}>Text 2</Text>
<Text style=\{\{padding:10,fontSize:42}}>Text 3</Text>
<Text style=\{\{padding:10,fontSize:42}}>Text 4</Text>
<Text style=\{\{padding:10,fontSize:42}}>Text 5</Text>
<Text style=\{\{padding:10,fontSize:42}}>Text 6</Text>
<Text style=\{\{padding:10,fontSize:42}}>Text 7</Text>
<Text style=\{\{padding:10,fontSize:42}}>Text 8</Text>
<Text style=\{\{padding:10,fontSize:42}}>Text 9</Text>
<Text style=\{\{padding:10,fontSize:42}}>Text 10</Text>
<Text style=\{\{padding:10,fontSize:42}}>Text 11</Text>
<Text style=\{\{padding:10,fontSize:42}}>Text 12</Text>
<TextInput style={styles.input}
placeholder="Type some text...">
</TextInput>
</ScrollView>
</KeyboardAvoidingView>

The below code solved my issue

<KeyboardAvoidingView
style=\{\{ flex: 1, flexDirection: 'column',justifyContent: 'center'}}
behavior={Platform.OS == "ios" ? "padding" : "height"}
keyboardVerticalOffset={150}
enabled>
{renderForm()}  // renderForm render the long form with ScrollView
</KeyboardAvoidingView>

After so many attempts, this is the one that works fine both for iOS & Android:

<KeyboardAvoidingView
style={styles.keyboard}
behavior={Platform.OS == "ios" ? "padding" : "height"}
enabled
keyboardVerticalOffset={10}
>
<ScrollView>
...
</ScrollView>
</KeyboardAvoidingView>

As for the style:

const styles = StyleSheet.create({
keyboard: {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
}
});

Not the perfect behavior in ios platform , use KeyboardAwareScrollView instead of KeyboardAvoidingView.

<View style=\{\{flex:1}}>
<KeyboardAvoidingView
style=\{\{flex:1}}
behavior={Platform.OS === 'ios' ? 'position' : null}
keyboardVerticalOffset={Platform.OS === 'ios' ? 50 : 70}
>
<ScrollView> // no need to put here style=\{\{flex:1}}
<TextInput />
<TextInput />
<TextInput />
<TextInput />
</ScrollView>
</KeyboardAvoidingView>
</View>

I have tried 2days to find proper solution and finally I found that.

<KeyboardAvoidingView
style=\{\{flex:1 }}
keyboardVerticalOffset={40 }
behavior={Platform.OS === "ios" ? "padding" : null}
>
<ScrollView >
….. .. . .
…
</ScrollView>
</KeyboardAvoidingView>

You just have to give special attention for TextInput because it does not work on multiline TextInput, For that the solution is

<TextInput
multiline={true}
scrollEnabled={false}
/>

Hope this will work for you and save your time.

I spent couple of hours with iPhone 13 simulator, android pixel 2, and iPhone 8 device. This is the solution:

<SafeAreaView style=\{\{ flex: 1 }}>
<Button />
<Text />


<KeyboardAvoidingView behavior={Platform.OS === "ios" ? "padding" : null}  keyboardVerticalOffset={50} style=\{\{ flex: 1 }}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<ScrollView>
<View style=\{\{ flexDirection: "row", alignItems: "center" }}>
<Button />
</View>
<Text> </Text>
<View style=\{\{ flexDirection: "row", alignItems: "center" }}>
<TextInput />
<TextInput />
<TextInput />
<TextInput />
</View>


<TextInput />


<View style=\{\{ flexDirection: "row", alignItems: "center" }}>
<TextInput />
<TextInput />
<TextInput />
</View>
<TextInput />
</ScrollView>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
<Button />
</SafeAreaView>

Also

keyboardVerticalOffset={100}

would not work with iOS device, leaving a blank view at the bottom of the scroll view above the button. moving the button inside the ScrollView would not help.