Closed QuangBinhDinh closed 1 year ago
In case of the error in the snack, the problem is that GestureHandlerRootView
is not a default export, so you would need to change:
import GestureHandlerRootView from 'react-native-gesture-handler';
to
import { GestureHandlerRootView } from 'react-native-gesture-handler';
You could also try using https://github.com/gorhom/react-native-bottom-sheet, as it already handles a lot of edge cases between platforms and could save you a lot of time 😄.
@j-piasecki Thanks for advice. I just try react-native-bottom-sheet
and seem like it does not work like I expect. The library doesn't have "skipping snap point" function, which every time I want to close my modal, it stops at the middle and not close immediately. I think I will follow my current code right now, however I just found even wrap GestureHandlerRootView
the modal doesn't receive event on Android. Is it because Modal
considered outside React Native hierarchy view?
IIRC, Modal
creates a separate root, so you would need to wrap the contents of Modal
with another GestureHandlerRootView
.
@j-piasecki
I'm trying to create a modal/bottom-sheet like this one. If you can come up with any idea I would very appreciate.
I think something like this would work:
import React, { useCallback, useMemo, useRef } from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
import BottomSheet from '@gorhom/bottom-sheet';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
const App = () => {
// ref
const bottomSheetRef = useRef<BottomSheet>(null);
// variables
const snapPoints = useMemo(() => ['50%', '100%'], []);
// callbacks
const handleSheetChanges = useCallback((from: number, to: number) => {
console.log('handleAnimate', from, to);
if (to === 0) {
bottomSheetRef.current?.forceClose();
}
}, []);
// renders
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<View style={styles.container}>
<Button
title="Open"
onPress={() => {
bottomSheetRef.current?.snapToIndex(0);
}}
/>
<BottomSheet
ref={bottomSheetRef}
index={0}
snapPoints={snapPoints}
enablePanDownToClose={true}
onAnimate={handleSheetChanges}>
<View style={styles.contentContainer}>
<Text>Awesome 🎉</Text>
</View>
</BottomSheet>
</View>
</GestureHandlerRootView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 24,
backgroundColor: 'grey',
},
contentContainer: {
flex: 1,
alignItems: 'center',
},
});
export default App;
Thanks for your recommend. I finally use BottomSheetModal
with some additional props and it works. Close this issue now
Description
I'm creating a swipeable modal using
react-native-gesture-handler
andreact-native-modal
. When open a modal, it only show half of a screen, user can swipe up to expand it to full screen (show more detail). Inside modal I have aScrollView
showing content. WhenScrollView
is scrolled to top, if user continue to swipe down modal will slowly go down and disappear if the user swipes past a certain threshold. First time implement I recognize that while scrolling PanGesture cannot receive event, which my modal cannot translate. I fix this on IOS by usingbounce
property, causecontentOffset.y
can go below zero and my modal can translate depend on that. Butbounce
doesn't exist on Android and I still don't have a solution. Here is my Snack repo: https://snack.expo.dev/@quangbinh1999/swipeable-modalOn IOS it's almost perfect (I still don't want to use
bounce
because it created a black space which looks not nice). On Android I cannot swipe down to close modal while it's full screen, I have to touch outside it. Also for some reason I try to wrapGestureHandlerRootView
but it keep getting an error on my Snack. I really appreciate someone can help me fix my code.Steps to reproduce
Above
Snack or a link to a repository
https://snack.expo.dev/@quangbinh1999/swipeable-modal
Gesture Handler version
2.5.0
React Native version
0.66.4
Platforms
Android, iOS
JavaScript runtime
None
Workflow
None
Architecture
Paper (Old Architecture)
Build type
Debug mode
Device
Android emulator
Device model
No response
Acknowledgements
Yes