react-native-bottom-sheet
react-native-bottom-sheet copied to clipboard
[v4] animatedKeyboardHeightInContainer is 0 when Keyboard is open
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
:

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
- Open
BottomSheetModal
which contains a text field by tapping onPresent Modal
button. - If the bug doesn’t reproduce, close
BottomSheetModal
by clicking ondone
keyboard button and repeat point 1. - 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;
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).
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>
);
}
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
this will be fixed with v5
this will be fixed with
v5
Is there an eta on v5 release date?
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.