Reputation: 1307
I'm using React Navigation 5+
. They have changed the way you configure Navigators and I'm trying to implement it in my program. I have a DrawerNavigator
as a top-level navigator. The first screen is a StackNavigator
with a few screens. I'm looking for a way to prevent the user from swiping the drawer open on every screen except for the first screen. Here is my Navigator file:
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
As you can see I have attempted to set gestureEnabled
to false on every screen but one (which is my main screen). It has no effect. If I set gestureEnabled
to false on the navigator itself, it prevents the drawer swipe gesture on all of the screens.
I have attempted code like this inside the screen:
CheckInFormScreen.navigationOptions = navData => {
return {
gestureEnabled: false
}
};
I didn't really expect this to work but I was just throwing stuff out there. How can I allow the user to swipe open the Drawer on the SearchLocationsScreen of the NavigationStack but not on the rest of the NavigationStack
's screens?
Upvotes: 0
Views: 2325
Reputation: 1307
Ok, I understand that React-Native is a bit of a buggy process. I did however figure a solution to my problem.
To solve the problem I got a reference to the parent navigator using dangerouslyGetParent
and then set the options on it.
Keep in mind, you use options when configuring a screen and you use screenOptions when you are configuring all the screens in the navigator. These props replace navigationOptions
and defaultNavigationOptions
from react-navigation 4+
Here is the full code:
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
Upvotes: 6
Reputation: 4199
Update: If the below code doesnt work , Please refer Screen options resolution
Did you try using 'drawerLockMode'
FeedStack.navigationOptions = () => {
return { drawerLockMode: 'locked-closed' }
}
I think you can add this prop in options
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>
);
}
Upvotes: 1