react-native-bottom-sheet icon indicating copy to clipboard operation
react-native-bottom-sheet copied to clipboard

[v4] animatedKeyboardHeightInContainer is 0 when Keyboard is open

Open dNadiia opened this issue 2 years ago • 6 comments

Bug

In some random cases, BottomSheetModal doesn't open correctly when it contains a text field. In such buggy cases animatedKeyboardHeightInContainer.value is rewriting to 0 after a keyboard was opened, because of true for !isAnimatedOnMount.value condition in src/components/bottomSheet/BottomSheet.tsx:

image

Note: bug is reproduced for any value of keyboardBehavior

Logs

LOG  =========WITHOUT BUG===========
LOG  
LOG  _keyboardState 0
LOG  _keyboardHeight 0
LOG  animatedKeyboardHeightInContainer 0
LOG  
LOG  !isAnimatedOnMount true
LOG  set animatedKeyboardHeightInContainer to zero 0
LOG  

LOG  _keyboardState 1
LOG  _keyboardHeight 291
LOG  animatedKeyboardHeightInContainer 291
LOG  

LOG  _keyboardState 2
LOG  _keyboardHeight 291
LOG  animatedKeyboardHeightInContainer 291
LOG  
LOG  !isAnimatedOnMount false
LOG  set animatedKeyboardHeightInContainer to zero 0
LOG  



LOG  =========WITH BUG===========
LOG  
LOG  _keyboardState 0
LOG  _keyboardHeight 0
LOG  animatedKeyboardHeightInContainer 0
LOG  
LOG  !isAnimatedOnMount true
LOG  set animatedKeyboardHeightInContainer to zero 0
LOG  

LOG  _keyboardState 1
LOG  _keyboardHeight 291
LOG  animatedKeyboardHeightInContainer 291
LOG  
LOG  !isAnimatedOnMount true
LOG  set animatedKeyboardHeightInContainer to zero 0 
LOG  

LOG  _keyboardState 2
LOG  _keyboardHeight 291
LOG  animatedKeyboardHeightInContainer 291
LOG  
LOG  !isAnimatedOnMount false
LOG  set animatedKeyboardHeightInContainer to zero 0

Video

https://user-images.githubusercontent.com/12046657/192360276-5b7665d4-7728-4d7b-a0a0-1b6bd3794d6c.mp4

Environment info

Library Version
@gorhom/bottom-sheet 4.4.5
react-native 0.68.2
react-native-reanimated 2.10.0
react-native-gesture-handler 2.6.2

Steps To Reproduce

  1. Open BottomSheetModal which contains a text field by tapping on Present Modal button.
  2. If the bug doesn’t reproduce, close BottomSheetModal by clicking on done keyboard button and repeat point 1.
  3. If you didn't catch the bug after 10-15 consecutive attempts, try to reload the app and start one more time from point 1.

Describe what you expected to happen:

The BottomSheetModal with a text field inside is opened according to the keyboardBehavior parameter every time the present method of the modal is called.

Reproducible sample code

import React, { useCallback, useMemo, useRef } from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { BottomSheetModal, BottomSheetTextInput } from '@gorhom/bottom-sheet';

const App = () => {
  // ref
  const bottomSheetModalRef = useRef(null);

  // variables
  const snapPoints = useMemo(() => ['50%', '90%'], []);

  // callbacks
  const openModal = useCallback(() => {
    bottomSheetModalRef.current?.present();
  }, []);

  const dismissModal = useCallback(() => {
    bottomSheetModalRef.current?.dismiss();
  }, []);

  // renders
  return (
    <View style={styles.container}>
      <Button onPress={openModal} title="Present Modal" color="black" />
      <BottomSheetModal
        ref={bottomSheetModalRef}
        snapPoints={snapPoints}
        enablePanDownToClose={true}
        keyboardBehavior={'extend'}
        android_keyboardInputMode={'adjustResize'}
      >
        <View style={styles.contentContainer}>
          <BottomSheetTextInput
            autoFocus={true}
            returnKeyType={'done'}
            style={styles.input}
            onSubmitEditing={dismissModal}
          />
          <Text>{'Item 1'}</Text>
          <Text>{'Item 2'}</Text>
          <Text>{'Item 3'}</Text>
        </View>
      </BottomSheetModal>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 24,
    justifyContent: 'center',
    backgroundColor: 'yellow',
  },
  contentContainer: {
    flex: 1,
    padding: 20,
  },
  input: {
    marginTop: 8,
    marginBottom: 10,
    borderRadius: 10,
    fontSize: 16,
    lineHeight: 20,
    height: 50,
    padding: 8,
    backgroundColor: 'pink',
  },
});

export default App;

dNadiia avatar Sep 26 '22 21:09 dNadiia

thank god. I thought this issue was related to my very application but it seems to be a known problem. what I noticed for my app:

I have a couple of input fields in the bottom sheet and previously set the auto-focus to the first input field. since I continuously had problems with this approach, I removed that and instead manually set the focus 500ms after the bottom sheet was rendered. this improves the situation quite a bit but obviously is a hack. What makes things a bit more cumbersome: in same cases, I'm accessing the clipboard of the user and iOS asks the user if he wants to allow my app to access the clipboard. In this situation, the UI is already rendered but the OS dialog opens with the question if the clipboard can be access or not. if I now press yes and render the input of the clipboard in the bottom sheet, the height oft the content increases which causes the keyboard to overlap the bottom sheet because it apparently no longer reacts to the increased content height. (it does notice the height change however since the onlayout event is triggered and you can see that the height is increasing).

sdepold avatar Oct 01 '22 12:10 sdepold

Reproducible sample code

import BottomSheet, {
  BottomSheetTextInput,
  BottomSheetView,
  TouchableOpacity,
  useBottomSheetDynamicSnapPoints,
} from "@gorhom/bottom-sheet";
import React, { useMemo, useState } from "react";
import { Text, View } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";

export default function App(): React.ReactElement | null {
  const [value, setValue] = useState("Hello world");
  const [boxHeight, setBoxHeight] = useState(10);
  const initialSnapPoints = useMemo(() => ["10%", "CONTENT_HEIGHT"], []);
  const {
    animatedHandleHeight,
    animatedSnapPoints,
    animatedContentHeight,
    handleContentLayout,
  } = useBottomSheetDynamicSnapPoints(initialSnapPoints);

  return (
    <GestureHandlerRootView style={{ flex: 1, backgroundColor: "grey" }}>
      <BottomSheet
        index={1}
        snapPoints={animatedSnapPoints}
        handleHeight={animatedHandleHeight}
        contentHeight={animatedContentHeight}
      >
        <BottomSheetView onLayout={handleContentLayout} style={{ padding: 10 }}>
          <TouchableOpacity
            onPress={() => {
              setBoxHeight(boxHeight + 50);
            }}
            style={{ alignItems: "center" }}
          >
            <Text>Expand</Text>
          </TouchableOpacity>
          <BottomSheetTextInput
            value={value}
            onChangeText={setValue}
            style={{ padding: 10, textAlign: "center" }}
            autoFocus
          />
          <View
            style={{
              width: "100%",
              height: boxHeight,
              backgroundColor: "blue",
            }}
          ></View>
        </BottomSheetView>
      </BottomSheet>
    </GestureHandlerRootView>
  );
}

sdepold avatar Oct 01 '22 14:10 sdepold

With autofocus it is just hiding behind the keyboard: https://user-images.githubusercontent.com/79163/193413190-cd47ca51-e4cf-4252-bf9b-ea489a1a777a.mp4

Without autofocus: you'll see an expand button that will increase the height of the blue area at the bottom. I didn't fully understand under which circumstances it actually rearranges the bottom sheet but you can clearly see how sometimes it just doesn't adjust the position at all. It's also odd that the view doesn't move down again, when I close the keyboard

https://user-images.githubusercontent.com/79163/193413348-1644ed51-a222-4d6d-bf9c-e39f33954a85.mp4

I'm basically looking for a way to have a box with custom and partially dynamic height at the bottom of my screen which moves upwards if the keyboard is open

sdepold avatar Oct 01 '22 14:10 sdepold

this will be fixed with v5

gorhom avatar Oct 03 '22 18:10 gorhom

this will be fixed with v5

Is there an eta on v5 release date?

wadey1 avatar Jan 05 '23 09:01 wadey1

Still experiencing this issue. Publishing it as a pre-release tagged 5.0.0-alpha.5 would be extremely beneficial if this problem has been solved.

manuthecoder avatar Dec 31 '23 06:12 manuthecoder