如何防止导航器的抽屉滑动手势

How to prevent drawer swipe gesture from a navigator

我正在使用 React Navigation 5+。他们已经改变了你配置导航器的方式,我正试图在我的程序中实现它。我有一个 DrawerNavigator 作为顶级导航器。第一个屏幕是 StackNavigator,有几个屏幕。我正在寻找一种方法来防止用户在除第一个屏幕之外的每个屏幕上滑动打开抽屉。这是我的导航器文件:

const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();

function CheckinStack() {
    return (
        <Stack.Navigator
            initialRouteName={"Loading"}
            headerMode={"none"}
        >
            <Stack.Screen 
                name={"Search Locations"} 
                component={SearchLocationsScreen} 
                options={{gestureEnabled: true}}
            />
            <Stack.Screen 
                name={"Check In Form"} 
                component={CheckInFormScreen} 
                options={{gestureEnabled: false}}
            />
            <Stack.Screen 
                name={"Checked In"} 
                component={CheckedInScreen} 
                options={{gestureEnabled: false}}
            />
            <Stack.Screen 
                name={"Business Details"} 
                component={BusinessDetailsScreen} 
                options={{gestureEnabled: false}}
            />
        </Stack.Navigator>
    );
}

function MainDrawer() {
    return (
        <Drawer.Navigator >
            <Drawer.Screen name={"Search Locations"} component={CheckinStack}/>
            <Drawer.Screen name={"About"} component={AboutScreen}/>
            <Drawer.Screen name={"Favorites"} component={FavoritesScreen}/>
            <Drawer.Screen name={"Profile"} component={ProfileScreen}/>
            <Drawer.Screen name={"Report Issues"} component={ReportIssuesScreen}/>
        </Drawer.Navigator>
    );
}

const NavContainer = (props) => {
    return (
        <NavigationContainer>
            <MainDrawer />
        </NavigationContainer>
    )
};

export default NavContainer

如您所见,我尝试在除一个(我的主屏幕)之外的每个屏幕上将 gestureEnabled 设置为 false。它没有效果。如果我在导航器本身上将 gestureEnabled 设置为 false,它会阻止所有屏幕上的抽屉滑动手势。

我在屏幕内尝试过这样的代码:

CheckInFormScreen.navigationOptions = navData => {
    return {
        gestureEnabled: false
    }
};

我真的没想到这会起作用,但我只是把东西扔在那里。我如何允许用户在 NavigationStack 的 SearchLocationsScreen 上滑动打开抽屉,而不是在 NavigationStack 的其余屏幕上滑动打开?

更新:如果下面的代码不起作用,请参考屏幕选项解决

你试过使用'drawerLockMode'

FeedStack.navigationOptions = () => {
   return { drawerLockMode: 'locked-closed' }
}

我想你可以在选项中添加这个道具

function CheckinStack() {
    return (
        <Stack.Navigator
            initialRouteName={"Loading"}
            headerMode={"none"}
        >
            <Stack.Screen 
                name={"Search Locations"} 
                component={SearchLocationsScreen} 
            />
            <Stack.Screen 
                name={"Check In Form"} 
                component={CheckInFormScreen}
                options={{drawerLockMode: 'locked-closed'}} 
            />
            <Stack.Screen 
                name={"Checked In"} 
                component={CheckedInScreen}
                options={{drawerLockMode: 'locked-closed'}}
            />
            <Stack.Screen 
                name={"Business Details"} 
                component={BusinessDetailsScreen} 
                options={{drawerLockMode: 'locked-closed'}}
            />
        </Stack.Navigator>
    );
}

好的,我知道 React-Native 是一个有问题的过程。不过,我确实找到了解决问题的方法。

为了解决这个问题,我使用 dangerouslyGetParent 获得了对父导航器的引用,然后在其上设置了选项。

请记住,在配置屏幕时使用 options,在导航器中配置所有屏幕时使用 screenOptions .这些道具替换了反应导航 4+

中的 navigationOptionsdefaultNavigationOptions

完整代码如下:

const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();

function CheckinStack({props}) {
    return (
        <Stack.Navigator
            initialRouteName={"Loading"}
            headerMode={"none"}
        >
            <Stack.Screen
                name={"Loading"}
                component={LoadingScreen}
                options={props => {
                    let parent = props.navigation.dangerouslyGetParent();
                    parent.setOptions({
                        gestureEnabled: false
                    })
                }}
            />
            <Stack.Screen
                name={"Search Locations"}
                component={SearchLocationsScreen}
                options={props => {
                    let parent = props.navigation.dangerouslyGetParent();
                    parent.setOptions({
                        gestureEnabled: true
                    })
                }}
            />
            <Stack.Screen
                name={"Check In Form"}
                component={CheckInFormScreen}
                options={props => {
                    let parent = props.navigation.dangerouslyGetParent();
                    parent.setOptions({
                        gestureEnabled: false
                    })
                }}
            />
            <Stack.Screen
                name={"Checked In"}
                component={CheckedInScreen}
                options={props => {
                    let parent = props.navigation.dangerouslyGetParent();
                    parent.setOptions({
                        gestureEnabled: false
                    })
                }}
            />
            <Stack.Screen
                name={"Business Details"}
                component={BusinessDetailsScreen}
                options={props => {
                    let parent = props.navigation.dangerouslyGetParent();
                    parent.setOptions({
                        gestureEnabled: false
                    })
                }}
            />
        </Stack.Navigator>
    );
}

function MainDrawer() {
    return (
        <Drawer.Navigator >
            <Drawer.Screen name={"Search Locations Stack"} component={CheckinStack}/>
            <Drawer.Screen name={"About"} component={AboutScreen}/>
            <Drawer.Screen name={"Favorites"} component={FavoritesScreen}/>
            <Drawer.Screen name={"Profile"} component={ProfileScreen}/>
            <Drawer.Screen name={"Report Issues"} component={ReportIssuesScreen}/>
        </Drawer.Navigator>
    );
}

const NavContainer = (props) => {
    return (
        <NavigationContainer>
            <MainDrawer />
        </NavigationContainer>
    )
};

export default NavContainer