Reputation: 85
I'm having trouble getting my KeyboardAvoidingView to register properly on the iOS version of my react-native app. It's nested within another view in my ListFooterComponent
of a Flatlist. The behavior is relatively normal on Android, but is not working at all on iOS.
Things I've tried:
behavior
prop (all 3 props didn't end up working)keyboardVerticalOffset
prop (no amount of offset managed to change anything, it just adds a bunch of padding to the bottom of the screen)KeyboardAvoidingView
tag to the outermost view in ListFooterComponent
. No differenceflex: 1
to inner and outer componentsI have seen other posts recommending using other keyboard avoidance libraries, but since this is an Expo Managed project, I don't think these will work for me. Any advice for how to accomplish this using the KeyboardAvoidingView component only?
This is a screenshot of the screen without a keyboard on iOS: this
And this is a screenshot of with a keyboard on iOS: this
And here's the code:
<SafeAreaView style={{ flex: 1 }}>
<FlatList
data={commentData}
style={{ flex: 1 }}
keyboardDismissMode={'on-drag'}
keyboardShouldPersistTaps={'always'}
keyExtractor={item => (item.id)}
renderItem={({ item }) => {
return (
<>
</>
)
}}
ListFooterComponent={() => {
return (
<>
<View style={{ borderColor: "#D6DCE8", marginBottom: 0, borderTopWidth: 2, marginTop: 25, shadowColor: "#000", shadowRadius: 2, shadowOpacity: 0.25, shadowOffset: { width: 0, height: 2 }, elevation: 5 }} />
<View style={{ flex: 1, flexDirection: 'row', paddingTop: 15, paddingBottom: 15 }}>
<TouchableOpacity delayPressIn={20}>
<View style={styles.commentImage}>
<Image source={{ uri: myProfilePicture }} style={styles.image}></Image>
</View>
</TouchableOpacity>
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
keyboardVerticalOffset={Platform.select({ ios: 100, android: 500 })}
style={{ flex: 1, backgroundColor: '#ECECEC', borderRadius: 10, flex: 0.95, paddingVertical: 5, marginLeft: 10 }}>
<TextInput style={{
fontSize: 14,
fontWeight: '500',
paddingHorizontal: 10,
marginHorizontal: 10,
paddingVertical: 6,
flex: 1,
flexDirection: 'row',
flexWrap: 'wrap'
}}
ref={commentRef}
multiline={true}
blurOnSubmit={true}
numberOfLines={2}
onFocus={() => commentRef.current = true}
onBlur={() => commentRef.current = false}
placeholder="Leave a comment..."
defaultValue={comment}
onChangeText={(newValue) => { comment = newValue }}
onSubmitEditing={() => submitComment()} />
</KeyboardAvoidingView>
</View>
<View style={Platform.OS === 'android' ? { marginBottom: 200 } : { marginBottom: 100 }} />
</>
)
}}
ListHeaderComponent={() => {
return (
<>
</>
)
}}
/>
</SafeAreaView>
Upvotes: 5
Views: 9200
Reputation: 2185
For the above layout, use KeyboardAvoidingView
above FlatList
in your hierarchy, and place the comment box not as the footer, but outside of the list component altogether.
Here's a snack with these changes (OP's code simplified for context): https://snack.expo.dev/@mlisik/thankful-tortilla
A few general notes:
padding
behaviour should be what you wantkeyboarVerticalOffset
is useful if your view is nested inside a navigator (eg. from react-navigation
), and navigation bar or tabbar are visible - you should then set the value to the height of those barsUpvotes: 3