Expo中如何实现支持下滑关闭的全屏模态框?
实现Expo全屏可下滑关闭的模态框
方案一:基于modal类型自定义全屏样式
modal类型默认支持下滑关闭,只需将页面内容设置为全屏即可:
- 给目标屏幕的根组件设置全屏样式:
import { View, StyleSheet, StatusBar } from 'react-native'; export default function IndexScreen() { return ( <View style={styles.container}> {/* 你的页面内容 */} </View> ); } const styles = StyleSheet.create({ container: { flex: 1, marginTop: StatusBar.currentHeight, // 适配状态栏高度 backgroundColor: '#fff', // 确保背景覆盖全屏 }, });
- 保持导航配置的
presentation: "modal",同时调整动画和头部设置:
<Stack.Screen name="index" options={{ animation: "slide_from_bottom", headerShown: false, animationDuration: 400, presentation: "modal", }} />
此方案既保留modal的原生下滑关闭手势,又通过样式实现全屏显示。
方案二:给fullScreenModal添加手动下滑关闭手势
如果必须使用fullScreenModal,可通过expo-gesture-handler实现下滑关闭逻辑:
- 安装依赖(未安装时执行):
npx expo install expo-gesture-handler react-native-gesture-handler
- 在屏幕组件中添加手势监听:
import { View, StyleSheet } from 'react-native'; import { GestureDetector, Gesture } from 'react-native-gesture-handler'; import { useNavigation } from '@react-navigation/native'; export default function IndexScreen() { const navigation = useNavigation(); // 创建下滑手势检测逻辑 const panGesture = Gesture.Pan() .onEnd((event) => { // 滑动距离超过阈值时关闭模态框 if (event.translationY > 100) { navigation.goBack(); } }); return ( <GestureDetector gesture={panGesture}> <View style={styles.container}> {/* 你的页面内容 */} </View> </GestureDetector> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', }, });
- 导航配置保持
presentation: "fullScreenModal":
<Stack.Screen name="index" options={{ animation: "slide_from_bottom", headerShown: false, animationDuration: 400, presentation: "fullScreenModal", }} />
该方案通过手动监听手势动作,为fullScreenModal补上下滑关闭功能。
方案三:自定义React Navigation的presentation(进阶)
通过修改modal类型的卡片样式,实现全屏+原生下滑关闭的原生体验:
import { createStackNavigator } from '@react-navigation/stack'; const Stack = createStackNavigator(); // 自定义全屏可关闭的modal配置 const FullScreenDismissableModal = { presentation: 'modal', cardStyle: { flex: 1, margin: 0, // 移除modal默认的边距 }, }; // 导航中使用自定义配置 <Stack.Navigator> <Stack.Screen name="index" options={{ ...FullScreenDismissableModal, animation: "slide_from_bottom", headerShown: false, animationDuration: 400, }} /> </Stack.Navigator>
内容的提问来源于stack exchange,提问作者Muhammad Daniyal Jawad
相关产品推荐
相关产品推荐

