Как запретить жест смахивания ящика из навигатора

Я использую 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
    }
};

Я действительно не ожидал, что это сработает, но я просто выбрасывал туда вещи. Как я могу разрешить пользователю открыть Drawer на экране SearchLocationsScreen NavigationStack, но не на остальных экранах NavigationStack?


person Jo Momma    schedule 09.03.2020    source источник


Ответы (2)


Хорошо, я понимаю, что React-Native — это немного глючный процесс. Однако я нашел решение своей проблемы.

Чтобы решить проблему, я получил ссылку на родительский навигатор, используя dangerouslyGetParent, а затем установил для него параметры.

Имейте в виду, что вы используете options при настройке экрана, а screenOptions — при настройке всех экранов в навигаторе. Эти реквизиты заменяют navigationOptions и defaultNavigationOptions из реагирующей навигации 4+.

Вот полный код:

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
person Jo Momma    schedule 11.03.2020

Обновление: если приведенный ниже код не работает, см. Разрешение параметров экрана

Вы пытались использовать '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>
    );
}
person Victor    schedule 10.03.2020
comment
Похоже, что ни один из параметров экрана не имеет никакого эффекта. - person Jo Momma; 10.03.2020