KeyboardAvoidingView leaves white space when user navigates to prev screen using swipe gesture in react native
Description
I am trying to build a react native app but have navigation issues. When the user navigates between screens using gestures, I believe KeyboardAvoidingView creates empty space on the screen. In the following example. When the user swipes back from FormMainScreen to HomeScreen while the keyboard is active, an empty space appears on the Homepage.
Version
0.68.2
Output of npx react-native info
info Fetching system and libraries information... System: OS: macOS 12.2.1 CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz Memory: 31.74 MB / 16.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 16.13.0 - /usr/local/bin/node Yarn: Not Found npm: 8.1.0 - /usr/local/bin/npm Watchman: Not Found Managers: CocoaPods: 1.11.3 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: DriverKit 21.4, iOS 15.5, macOS 12.3, tvOS 15.4, watchOS 8.5 Android SDK: Not Found IDEs: Android Studio: 2021.2 AI-212.5712.43.2112.8512546 Xcode: 13.4.1/13F100 - /usr/bin/xcodebuild Languages: Java: 17.0.2 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 17.0.2 => 17.0.2 react-native: 0.68.2 => 0.68.2 react-native-macos: Not Found npmGlobalPackages:
Steps to reproduce
- Wrap "KeyboardAvoidingView" around the component where there is an input field and the user is able to pull up the keyboard. Note: this should be the second screen in the navigation stack. For eg. HomeScreen -> screen with keyboard input box
- Edit the input field so the keyboard pulls up
- Now, swipe back to the previous screen while keyboard is open
- Notice, once you land back to the previous screen, there is white space KeyboardAvoidingView
I have also created a question on StackOverflow https://stackoverflow.com/questions/73074125/keyboardavoidingview-leaves-white-space-when-user-navigates-to-prev-screen-using
Snack, code example, screenshot, or link to a repository
App.jsx
<Provider store={store}>
<NavigationContainer>
<SafeAreaProvider>
<KeyboardAvoidingView
style={{ flex: 1 }}
behavior={Platform.OS === "ios" ? "padding" : "height"}
keyboardVerticalOffset={Platform.OS === "ios" ? -10 : 0}
>
<MainNavigator />
</KeyboardAvoidingView>
</SafeAreaProvider>
</NavigationContainer>
</Provider>
MainNavigator component
const Stack = createNativeStackNavigator();
const MainNavigator = () => {
return (
<Stack.Navigator
screenOptions={{
headerShown: false
}}
initialRouteName="Welcome"
>
<Stack.Screen name="Welcome" component={HomeScreen} />
<Stack.Screen name="FormMain" component={Screen2} />
</Stack.Navigator>
);
};
Screen - 2 (With text field)

Swipe from left to right to back to the previous screen

Screen -1 ( Empty white space when you land back on the previous screen)

I had a similar problem, and got it working by patching the KeyboardAvoidingView in react-native:
diff --git a/node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js b/node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js
index 6a343d8..8affbbc 100644
--- a/node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js
+++ b/node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js
@@ -120,6 +120,8 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
}
};
+ finishedBottomSet = true;
+
_updateBottomIfNecessary = async () => {
if (this._keyboardEvent == null) {
this.setState({bottom: 0});
@@ -129,7 +131,7 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
const {duration, easing, endCoordinates} = this._keyboardEvent;
const height = await this._relativeKeyboardHeight(endCoordinates);
- if (this.state.bottom === height) {
+ if (this.state.bottom === height && this.finishedBottomSet === true) {
return;
}
@@ -143,7 +145,11 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
},
});
}
- this.setState({bottom: height});
+
+ this.finishedBottomSet = false
+ this.setState({bottom: height}, () => {
+ this.finishedBottomSet = true
+ })
};
componentDidMount(): void {
I faced the same issue on iOS. If the keyboard is open and the user navigates to the next screen, it would consider the keyboardVerticalOffset value and shift the bottom view to top. Tried dismissing the keyboard before navigation but still there was white space when navigating to the next screen.
Fixed it by checking if height is equal to keyboardVerticalOffset and then return instead of setting bottom state with height value.
Just faced this issue, and tried @buschco solution, it works like a charm.
| :warning: | Missing Reproducible Example |
|---|---|
| :information_source: | We could not detect a reproducible example in your issue report. Please provide either:
|
This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.
This issue was closed because it has been stalled for 7 days with no activity.