Reputation: 27
I want to be able to swipe down and close the full screen modal.
I tried React-native-modal, but it was not suitable for my app.
I tried the method using GestureRecognizer
on this page and was able to close the modal, but the modal did not go up and down according to the swipe, which is not ideal for me.
I want to close the full screen modal with an animation like when I specify pageSheet in presentationStyle.
If you know more about it, please let me know how to do it.
const RecordingModal = ({ open, close }) => {
return (
<Modal
animationType="slide"
onSwipeComplete={close}
presentationStyle="fullscreen"
visible={open}
>
<SafeAreaView style={styles.modal}>
<Text>aaaa</Text>
<Text>aaaa</Text>
</SafeAreaView>
</Modal>
);
};
Upvotes: 1
Views: 5015
Reputation: 8645
You can implement this behavior by using react-native-modal
, react-native-reanimated
plus react-native-gesture-handler
.
Here is an example:
import Animated, {
runOnJS,
useAnimatedGestureHandler,
useAnimatedStyle,
useSharedValue,
} from 'react-native-reanimated';
import { GestureHandlerRootView, PanGestureHandler } from 'react-native-gesture-handler';
import Modal from 'react-native-modal'
const SwipeableModal = () => {
const translateY = useSharedValue(0);
const gestureHandler = useAnimatedGestureHandler({
onStart: (_, ctx) => {
ctx.startY = translateY.value;
},
onActive: (event, ctx) => {
translateY.value = ctx.startY + event.translationY;
},
onEnd: _ => {
if (onClose) {
// replace `onClose` with your close function
runOnJS(onClose)();
}
},
});
const animatedStyle = useAnimatedStyle(() => {
return {
transform: [
{
translateY: translateY.value,
},
],
};
});
return (
<Modal isVisible={isVisible}>
<GestureHandlerRootView style={{flex:1}}>
<PanGestureHandler onGestureEvent={gestureHandler}>
<Animated.View style={[styles.myStyle, animatedStyle]}
{.... your modal UI here}
</Animated.View>
</PanGestureHnadler>
</GestureHandlerRootView>
</Modal>
)
}
export default SwipeableModal;
Upvotes: 0
Reputation: 6967
Try this way
<GestureRecognizer
style={{flex: 1}}
onSwipeUp={ () => this.setModalVisible(true) }
onSwipeDown={ () => this.setModalVisible(false) }
>
<Modal
animationType="slide"
presentationStyle="formSheet"
visible={ modalVisible }
>
<Text>Swipe Down Please</Text>
</Modal>
<Text>Swipe Up Please</Text>
</GestureRecognizer>
You can also use react-native-swipe-modal-up-down Following the usage
import SwipeUpDownModal from 'react-native-swipe-modal-up-down';
let [ShowComment, setShowModelComment] = useState(false);
let [animateModal, setanimateModal] = useState(false);
<SwipeUpDownModal
modalVisible={ShowComment}
PressToanimate={animateModal}
//if you don't pass HeaderContent you should pass marginTop in view of ContentModel to Make modal swipeable
ContentModal={
<View style={styles.containerContent}>
<FlatList
data={data}
renderItem={({item, index}) => (
<item key={index} Data={item} />
)}
keyExtractor={item => item.id}
/>
</View>
}
HeaderStyle={styles.headerContent}
ContentModalStyle={styles.Modal}
HeaderContent={
<View style={styles.containerHeader}>
<Button
Title={"Press Me"}
onPress={() => {
setanimateModal(true);
}}
/>
</View>
}
onClose={() => {
setModelComment(false);
setanimateModal(false);
}}
/>
const styles = StyleSheet.create({
containerContent: {flex: 1, marginTop: 40},
containerHeader: {
flex: 1,
alignContent: 'center',
alignItems: 'center',
justifyContent: 'center',
height: 40,
backgroundColor: '#F1F1F1',
},
headerContent:{
marginTop: 0,
},
Modal: {
backgroundColor: '#005252',
marginTop: 0,
}
});
Upvotes: 2