React导航- react native -如何阻止嵌套在抽屉导航器中的堆栈导航器中的抽屉?

vnjpjtjt  于 2023-02-13  发布在  React
关注(0)|答案(2)|浏览(201)

在我的react原生应用中,我有一个嵌套在抽屉式导航器中的堆栈导航器,我希望抽屉式导航器在堆栈导航器页面中被禁用,我使用的是react navigation 6。
在文档(https://reactnavigation.org/docs/drawer-navigator/#options)中,我看到有两个选项:gestureEnabled​swipeEnabled​.但是这些只能用在抽屉屏幕上,而不是像我的情况那样用在堆栈屏幕上。
我的代码如下:

const Stack = createNativeStackNavigator<RootStackParamList>();
const Drawer = createDrawerNavigator<RootTabParamList>();

const loginStack = () => (
  <Stack.Navigator>
    <Stack.Screen name="LandingScreen" component={LandingScreen} options={{ headerShown: false }} />
    <Stack.Screen name="LoginScreen" component={LoginScreen} options={{ headerShown: false }} />
    <Stack.Screen
      name="RegisterScreen"
      component={RegisterScreen}
      options={{ headerShown: false }}
    />
  </Stack.Navigator>
);

return (
  <NavigationContainer>
    <Drawer.Navigator
      screenOptions={{
        drawerStyle: { backgroundColor: 'white' },
        drawerPosition: 'right',
      }}
    >
      {!user ? (
        <Drawer.Screen
          name="PublicStack"
          component={loginStack}
          // options={{headerShown: false}}
          options={({ route }) => {
            const routeName = getFocusedRouteNameFromRoute(route);
            if (
              routeName === 'LandingScreen' ||
              routeName === 'LoginScreen' ||
              routeName === 'RegisterScreen'
            )
              return { swipeEnabled: false, gestureEnabled: false };
            return { swipeEnabled: true, gestureEnabled: true };
          }}
        />
      ) : (
        <>
          <Drawer.Screen
            name="Search cocktails"
            component={HomeScreen}
            options={{ header: () => <Header /> }}
          />
          <Drawer.Screen
            name="Profile"
            component={ProfileScreen}
            initialParams={{ userParam: null }}
            options={{ header: () => <Header /> }}
          />
          <Drawer.Screen
            name="Publish a recipe"
            component={PublishRecipeScreen}
            options={{ header: () => <Header /> }}
          />
          <Drawer.Screen
            name="Favorites"
            component={FavoritesScreen}
            options={{ header: () => <Header /> }}
          />
          <Drawer.Screen
            name="Published recipes"
            component={PublishedRecipesScreen}
            options={{ header: () => <Header /> }}
          />
          <Drawer.Screen
            name="Log out"
            component={CustomDrawerContent}
            options={{ header: () => <Header /> }}
          />

          <Drawer.Screen
            name="CocktailDetailScreen"
            component={CocktailDetailScreen}
            options={{
              header: () => <Header />,
              drawerLabel: () => null,
              title: undefined,
            }}
          />
        </>
      )}
    </Drawer.Navigator>
  </NavigationContainer>
);

我尝试过直接在loginStack抽屉式界面上设置上述选项,例如:

<Drawer.Screen
  name='PublicStack'
  component={loginStack}
  options={{swipeEnabled: false, gestureEnabled: false}}} 
/>

但没有成功。
我也看到了这个答案(How to disable drawer inside Stack Navigator nested inside Drawer Navigator?),并试图实现类似的东西(我的代码现在看起来像什么),但仍然没有工作。
完整的代码可以在这里找到:https://github.com/coccagerman/mixr
谢谢!

qc6wkl3g

qc6wkl3g1#

这些天来我一直在做同样的事情,我没有找到使用getFocusedRouteNameFromRoute(route)的解决方案,而是采取了不同的方法。
第一件事是在整个应用程序中阻止抽屉:

<Drawer.Navigator screenOptions = {{ swipeEnabled: false }}>
        <Drawer.Screen name="Screen1" component={StackScreen1} />
        <Drawer.Screen name="Screen2" component={StackScreen2} />
      </Drawer.Navigator>

然后,在所需的屏幕上启用抽屉,如下所示:

useFocusEffect(
        useCallback((() => {
          // From a Stack screen, the Drawer is accessed.
          const parent = navigation.getParent()
          parent?.setOptions({ swipeEnabled: true })
          // It returns to the initial state.
          return () => parent?.setOptions({ swipeEnabled: false })
        }, [navigation])
      )

如果您必须在多个屏幕上启用抽屉,则可以使用相反的方法。在整个应用程序中启用抽屉,并仅在所需的屏幕中阻止它。
我知道这可能不是最好的解决办法,但我希望它能帮助你。

blmhpbnm

blmhpbnm2#

在我的例子中,我只想在嵌套在抽屉式导航器中的堆栈导航器的第一个屏幕上启用滑动。
我在抽屉式屏幕周围建立了一个组,获得了焦点路径名称,并且只在它是堆栈导航器的第一条路径时才启用滑动。

<Drawer.Group
  screenOptions={({ route }) => ({
    swipeEnabled: getFocusedRouteNameFromRoute(route) === 'NameOfFirstScreenInStack',
  })}
>
  {..}
</Drawer.Group>

getFocuesRouteNameFromRoute没有很好的文档记录,但至少有一个guide在使用它。

相关问题