react-native: Wrong button position when using KeyboardAvoidingView in combination with SafeAreaView and autofocus
Description
I have an input with autoFocus, a SafeAreaView, and a KeyboardAvoidingView. However the Button which should have his position exactly above the keyboard gets some margin when using SafeAreaView in combination with autoFocus.
It is to mention that if I add a delay to autoFocus of around 250ms it is working as expected.
I’ve build an expo snack here: https://snack.expo.io/@simbob/keyboardavoidingview-bug
React Native version:
react: ~16.11.0 => 16.11.0
react-native: https://github.com/expo/react-native/archive/sdk-38.0.2.tar.gz => 0.62.2
Expected Results
Button should have the same position all time.
Steps To Reproduce
import React from "react";
import {
StyleSheet,
Text,
View,
TextInput,
KeyboardAvoidingView,
TouchableOpacity,
Keyboard,
SafeAreaView,
} from "react-native";
export default function App() {
return (
<SafeAreaView style={styles.container}>
<KeyboardAvoidingView style={styles.container} behavior="padding">
<View style={styles.top}>
<Text>Open up App.js to start working on your app!</Text>
<TextInput style={{ borderWidth: 1 }} autoFocus={true} />
</View>
<View style={styles.bottom}>
<TouchableOpacity
style={styles.loginScreenButton}
onPress={Keyboard.dismiss}
>
<Text style={styles.loginText}>Blur</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginHorizontal: 16,
},
top: {
flex: 0.7,
},
bottom: {
flex: 0.3,
justifyContent: "flex-end",
},
loginScreenButton: {
paddingTop: 10,
paddingBottom: 10,
backgroundColor: "#1E6738",
borderWidth: 1,
},
loginText: {
color: "#fff",
textAlign: "center",
},
});
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 24
- Comments: 20 (2 by maintainers)
Commits related to this issue
- KeyboardAvoidingView: update bottom height when frame height is changed (#36970) Summary: Fix this issue: https://github.com/facebook/react-native/issues/29499 - We should change the bottom height i... — committed to facebook/react-native by lyqandy a year ago
- KeyboardAvoidingView: update bottom height when frame height is changed (#36970) Summary: Fix this issue: https://github.com/facebook/react-native/issues/29499 - We should change the bottom height i... — committed to jeongshin/react-native by lyqandy a year ago
- KeyboardAvoidingView: update bottom height when frame height is changed (#36970) Summary: Fix this issue: https://github.com/facebook/react-native/issues/29499 - We should change the bottom height i... — committed to OlimpiaZurek/react-native by lyqandy a year ago
I’m on react-native 0.63.3 and still face this issue
+1
In my case it’s because of react-navigation.
My workaround:
I experience the same issue.
I can say that I see it on iOS only. It does not appear on most of the devices that I’ve tried. It appears on iPhone Xr.
Removing the
autoFocus
from the input solves the issue with the padding but introduces bad UX in my case 😦While the useEffect with the transitionEnded listener works, its a bit too large for my liking. I managed to solve this issue by firing the focus function using the onLayout prop. Also this error only happened with “email-address” keyboard type text inputs in my case.
Bonus: the focus happens a lot faster when navigating, giving you the behavior you were looking for.
This is still a (common?) issue with seemingly no good workaround. Could we have some dev input?
This does not consistent work from my testing. Looks like the react-navigation underlying issue makes the other workaround that uses ontransition end a more reliable solution.
Sort-of workaround is to wrap the TextInput component and focus the input manually (based on autofocus prop) with a little timeout. This breaks the screen transition animation if navigating (with react-navigation) to the next screen which also has
autofocus
on an input though. Unless you increase that timeout quite a bit (like 500ms), but then the keyboard lags for a while to open after the screen transition…this is a really common use case. are there any workaround people have found other than removing
autoFocus
?Hey guys, in my specific case, I was able to fix it by using
router.push()
instead of<Redirect/>
.Note 1: It is an workaround, not a proper fix Note 2: I am using
expo-router
, there might be an equivalent to other routers. Not sure what changed at render-level but hope to help other devs in the same circunstances.Before
After
@qardpeet great that you’ve found an even better workaround! Happy to see even better solutions 😃