react-native-bottom-sheet: [v4] BottomSheetScrollView causes extra padding to appear

Bug

Using a combination of BottomSheetModal, BottomSheetScrollView and BottomSheetTextInput with keyboardBehavior set to interactive will result in extra padding/margin appearing when the keyboard is visible - this only applies to Android, on iOS it seems to work as expected.

Environment info

Library Version
@gorhom/bottom-sheet 4.0.2
react-native 0.63
react-native-reanimated 2.1.0
react-native-gesture-handler 1.10.3

Steps To Reproduce

  1. Create a BottomSheetModal component that renders a BottomSheetScrollView and a small number of BottomSheetTextInputs
  2. Focus one of the lower TextInputs
  3. Extra padding/margin appears

Describe what you expected to happen:

  1. No extra padding/margin should render above the keyboard

Reproducible sample code

Below is a Snack containing a reproducible sample https://snack.expo.dev/@conorw/v4-bottomsheetscrollview-keyboard-padding-issue

and here are two videos showcasing the issue, one using the above Snack, and the other in my own Production app

https://user-images.githubusercontent.com/1332314/131832648-a60148cc-2c99-4207-9248-83139fd48b70.mp4

https://user-images.githubusercontent.com/1332314/131833763-bc0114ca-eed5-42bf-b01b-840731347f78.mp4

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Comments: 43 (6 by maintainers)

Commits related to this issue

Most upvoted comments

Adding android_keyboardInputMode='adjustResize' property worked for me

I also added:

keyboardBehavior='interactive'
keyboardBlurBehavior='restore'

i have tricky solution for this,

my problem was i had absolute view as my footer inside BottomSheetModal, and i had problem with adjustResize and adjustPan. if i set adjustResize the bottomsheet will going up like there is big margin with the keyboard. if i set adjustPan there will be a problem for smartphone with large screen only, the bottomsheet will sink to the back of the keyboard

adjustResize adjustPan
keyboard adjustresize keyboard adjustpan

my bottomsheet component FilterBottomSheet.js like this

      <View key={index} style={{ flex: 1 }}>
        <  style={styles.filterBottomSheetContent}>
          <View style={styles.filterSelectRadio}>
            <FilterData data={filterFormTemp} />
          </View>
        </ScrollView>

        <View style={styles.filterBottomSheetFooter}> // THIS IS ABSOLUTE VIEW AS FOOTER
          <Button
            style={[styles.filterBottomSheetButton, styles.filterBottomSheetReset]}
            onPress={() => _onPressFilter(name, 'reset')}
          >
            <OpenSansSemiBold style={styles.filterBottomSheetButtonText}>Reset</OpenSansSemiBold>
          </Button>

          <Button
            style={[styles.filterBottomSheetButton, styles.filterBottomSheetSimpan]}
            onPress={() => _onPressFilter(name, 'simpan', filterFormTemp)}
          >
            <OpenSansSemiBold style={[styles.filterBottomSheetButtonText, { color: Colors.colorLevel1 }]}>Simpan</OpenSansSemiBold>
          </Button>
        </View>
      </View>

i tried using BottomSheetView in my absolute View but the problem still occured. i tried BottomSheetScrollView as my ScrollView but the problem still occured, and other issue occured that it cannot be scrolled. (for this issue im using ScrollView from react-native-gesture-handler) i cannot used BottomSheetFooter because it’s in diffferent component from the parent BottomSheetModal

i tried everything from event focus input, keyboard listener in the component, all make the keyboard dismissed because it would rerender the component.

finally i solved this with created a keyboard listener in the parent that contain BottomSheetModal like this:

  useEffect(() => {
    let unmounted = false; // FLAG TO CHECK COMPONENT UNMOUNT
    // BUG FIXED BOTTOMSHEET FOR ABSOLUTE VIEW WHEN KEYBOARD SHOW
    const showSubscription = Keyboard.addListener("keyboardDidShow", () => {
      setKeyboardBottomInset(0.1);
    });
    const hideSubscription = Keyboard.addListener("keyboardDidHide", () => {
      setKeyboardBottomInset(0);
    });

    if (!unmounted) {
        ...
    }

    // CLEAR FUNCTION COMPONENT UNMOUNT
    return () => {
      unmounted = true;
      showSubscription.remove();
      hideSubscription.remove();
    }

  }, []);
  
    <BottomSheetModal
      key="filterHarga"
      ref={bottomSheetHargaRef}
      index={0}
      snapPoints={snapPoints}
      onChange={(index) => _filterChange("price", index)}
      backdropComponent={renderBackdrop}
      keyboardBehavior="fillParent"
      keyboardBlurBehavior="restore"
      bottomInset={keyboardBottomInset}
    >

please look setKeyboardBottomInset(0.1) and bottomInset={keyboardBottomInset} setKeyboardBottomInset(0.1) in the keyboardDidShow event listener would tricked the keyboard event to change the value bottomInset={keyboardBottomInset}

hope it helps!

I was having the same problem. Fixed by removing this logic:

diff --git a/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx b/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx
index 3606001..faf6e76 100644
--- a/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx
+++ b/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx
@@ -304,10 +304,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
       }
 
       return $modal
-        ? Math.abs(
-            animatedKeyboardHeight.value -
-              Math.abs(bottomInset - animatedContainerOffset.value.bottom)
-          )
+        ? Math.abs(bottomInset - animatedContainerOffset.value.bottom)
         : Math.abs(
             animatedKeyboardHeight.value - animatedContainerOffset.value.bottom
           );

Not sure if this will impact other parts of the package, still testing.

A more accurate code will be this:

diff --git a/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx b/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx
index b166440..ff40823 100644
--- a/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx
+++ b/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx

@@ -1366,9 +1365,11 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
          */
         animatedKeyboardHeightInContainer.value = $modal
           ? Math.abs(
-              _keyboardHeight -
-                Math.abs(bottomInset - animatedContainerOffset.value.bottom)
-            )
+            Platform.OS === 'android' &&
+            android_keyboardInputMode === KEYBOARD_INPUT_MODE.adjustResize ?
+              0 : _keyboardHeight
+              - Math.abs(bottomInset - animatedContainerOffset.value.bottom)
+          )
           : Math.abs(_keyboardHeight - animatedContainerOffset.value.bottom);
 
         const hasActiveGesture =

Since adjustResize will automatically adjust the screen size in android, there is no need to add the _keyboardHeight in the calculation.

android_keyboardInputMode=“adjustResize”

add the above, and padding issure resolved

For the people who happen to stumble upon this thread: what worked for me was setting android:windowSoftInputMode to adjustPan in the AndroidManifest.xml

@InfiniteRain according to Android docs adjustResize is preferable, so this is not the final solution. I think it works as a workaround but could potentially have side effects in UX depending on your use case of keyboard, adjustPan might overlap the view with the keyboard.

I actually got it working by setting keyboardBehavior="extend"

<RNBottomSheet
      ref={ref}
      snapPoints={animatedSnapPoints}
      handleHeight={animatedHandleHeight}
      contentHeight={animatedContentHeight}
      animateOnMount={false}
      onClose={onClose}
      backdropComponent={renderBackdrop}
      backgroundStyle={styles.backgroundStyle}
      handleIndicatorStyle={styles.handleIndicator}
      enablePanDownToClose
      keyboardBehavior="extend"
      keyboardBlurBehavior="restore"
    >

I was having the same problem. Fixed by removing this logic:

diff --git a/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx b/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx
index 3606001..faf6e76 100644
--- a/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx
+++ b/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx
@@ -304,10 +304,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
       }
 
       return $modal
-        ? Math.abs(
-            animatedKeyboardHeight.value -
-              Math.abs(bottomInset - animatedContainerOffset.value.bottom)
-          )
+        ? Math.abs(bottomInset - animatedContainerOffset.value.bottom)
         : Math.abs(
             animatedKeyboardHeight.value - animatedContainerOffset.value.bottom
           );

Not sure if this will impact other parts of the package, still testing.

A more accurate code will be this:

diff --git a/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx b/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx
index b166440..ff40823 100644
--- a/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx
+++ b/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx

@@ -1366,9 +1365,11 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
          */
         animatedKeyboardHeightInContainer.value = $modal
           ? Math.abs(
-              _keyboardHeight -
-                Math.abs(bottomInset - animatedContainerOffset.value.bottom)
-            )
+            Platform.OS === 'android' &&
+            android_keyboardInputMode === KEYBOARD_INPUT_MODE.adjustResize ?
+              0 : _keyboardHeight
+              - Math.abs(bottomInset - animatedContainerOffset.value.bottom)
+          )
           : Math.abs(_keyboardHeight - animatedContainerOffset.value.bottom);
 
         const hasActiveGesture =

Since adjustResize will automatically adjust the screen size in android, there is no need to add the _keyboardHeight in the calculation.

This worked like a charm. Thank you. For anyone wondering, this is using patch-package and creating a patch of the source code.

Wich solution is the best to adress the issue? Should i use the StackOverflow solution or rather use the fix in the package?

I used the StackOverflow link and worked like a charm

We’re also having this issue. Our team opened https://github.com/gorhom/react-native-bottom-sheet/issues/1195 to try and document before we saw this. We were able to fix on our end by doing two things:

  1. Not using BottomSheetScrollView
  2. Adding android_keyboardInputMode='adjustResize'

🐞 I’m facing the same problem on Android, I’m using the bottom sheet in version 4 and when focusing on my input, a very large padding is added just below the input and everything ends up being white.

I am using the same version 4, and facing same issue in Android. Have you somehow managed to make it work?

@gorhom many people including me seem to still encounter this problem of extra padding (around 32 pixels), any idea what could be causing it? It happens on both platforms and I already set keyboard window resize to adjustPan.

it worked for me when i changed KeyboardBehavior prop to “extend”

I was having the same problem. Fixed by removing this logic:

diff --git a/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx b/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx
index 3606001..faf6e76 100644
--- a/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx
+++ b/node_modules/@gorhom/bottom-sheet/src/components/bottomSheet/BottomSheet.tsx
@@ -304,10 +304,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
       }
 
       return $modal
-        ? Math.abs(
-            animatedKeyboardHeight.value -
-              Math.abs(bottomInset - animatedContainerOffset.value.bottom)
-          )
+        ? Math.abs(bottomInset - animatedContainerOffset.value.bottom)
         : Math.abs(
             animatedKeyboardHeight.value - animatedContainerOffset.value.bottom
           );

Not sure if this will impact other parts of the package, still testing.

Hey @gorhom, apologies for taking so long to get back to you!

Your suggestion absolutely makes sense, but unfortunately I am still able to replicate the issue. It seems as if the first input works ok, but the further you need to scroll down, the more the issue appears.

https://user-images.githubusercontent.com/1332314/133065110-8b5c8c0a-b04a-4488-9546-f21a2bdefdfa.mp4

I’ve also updated the Expo Snack I linked previously, which also still showcases the issue on Android

@RBrNx have you tried to change android_keyboardInputMode to your app android:windowSoftInputMode ? https://gorhom.github.io/react-native-bottom-sheet/props#android_keyboardinputmode