Как отключить прокрутку навигации по ящику только для одного из экранов навигатора?

#javascript #react-native #react-navigation

#javascript #react-native #реакция-навигация

Вопрос:

У меня есть пользовательский навигационный ящик, и на определенном экране я не хочу, чтобы он был доступен.

Это мой короткий код.

Этот навигатор также включается переключателем navigator. Я копался в git-hub и других форумах, и в настоящее время ничего не работает. Я что-то упускаю? Есть ли кто-нибудь, кто заставил это работать?

 const UserNavigation = createDrawerNavigator({
    ProductListScreen: {screen: ProductListScreen},
    ProductHistoryScreen: {
      screen: ProductHistoryScreen,
      navigationOptions: {
        drawerLockMode: 'locked-closed'
      }
    }
}, {
    initialRouteName: 'ProductListScreen',
    contentComponent: CustomDrawerContentComponent,
})

export default createAppContainer(UserNavigation)
  

Также есть рабочий код на expo, но я пытаюсь, и в результате отображаются двойные навигаторы, а также на экране, где я не хочу показывать появившийся ящик. Это моя попытка сослаться на expo code

 const UserStackNavigation = createStackNavigator({
  ProductListScreen: {screen: ProductListScreen},
  ProductHistoryScreen: {
    screen: ProductHistoryScreen
  }
})

const UserNavigation = createDrawerNavigator({
  UserStackNavigation: UserStackNavigation
}, {
  initialRouteName: 'UserStackNavigation',
  contentComponent: CustomDrawerContentComponent,
})

UserStackNavigation.navigationOptions = ({ navigation }) => ({
  drawerLockMode: navigation.state.index === 0 ? 'unlocked' : 'locked-closed',
});
export default createAppContainer(UserNavigation)
  

Ответ №1:

Вы можете задать параметры для каждого экрана, используя свойство «swipeEnabled». Пожалуйста, взгляните на соответствующую страницу документов;

https://reactnavigation.org/docs/drawer-navigator/#options

 <Drawer.Navigator initialRouteName="Feed">
  <Drawer.Screen
    name="Feed"
    component={Feed}
    options={{ swipeEnabled: false }}
  />
  <Drawer.Screen
    name="Profile"
    component={Profile}
    options={{ drawerLabel: 'Profile' }}
  />
</Drawer.Navigator>);}
  

Ответ №2:

В версии 5 вы можете использовать <Drawer.Navigator screenOptions={{ gestureEnabled: false }} ...>...</Drawer.Navigator>

Комментарии:

1. Первоначальный вопрос заключается в том, как отключить это только на определенном экране.

Ответ №3:

Проблема заключалась в том, что я использовал Ignite для создания шаблона моего проекта, а версия react-navigation была исправлена в версии 3.0.0. И после просмотра последнего комментария по этой ссылке я понял, что это не было проблемой с моим синтаксисом.

Итак, я удалил свою папку packed.lock.json, yarn.lock, node_modules, в package.json я установил версию как ^ 3.0.0, чтобы получить последнюю версию.

После всего этого я выполнил установку yarn для получения полного обновления пакета. С этим изменением мой react-navigation-drawer перешел с версии 1.0.1 на 1.3.0, и это устранило проблему.

Также внесены некоторые изменения в мою навигацию, которая теперь выглядит следующим образом:

 export default class UserNavigation extends React.Component{
  render(){
    return <Nav />
  }
}

const Nav = createAppContainer(
  createDrawerNavigator(
    {
      ProductListScreen: {screen: ProductListScreen},
      ProductHistoryScreen: {
        screen: ProductHistoryScreen,
          navigationOptions:{
            drawerLockMode: 'locked-closed'
          }
      }
    }, {
      initialRouteName: 'ProductListScreen',
      contentComponent: CustomDrawerContentComponent,
    }
  )
)
  

Ответ №4:

Чтобы отключить свайп / жест в одном маршруте в React Navigation V5:

Импортируйте помощник, чтобы получить текущее название маршрута

import { getFocusedRouteNameFromRoute } from '@react-navigation/native';

Проверьте, совпадает ли название маршрута с маршрутом, который вы хотите отключить прокруткой / жестом

 options={({ route }) => {
   const routeName = getFocusedRouteNameFromRoute(route);
   return {
     swipeEnabled: routeName !== 'Profile',
   };
}}
  

Ответ №5:

Я добавил код настройки навигации для отключения бокового меню для определенного экрана, это может быть кому-то полезно.

 import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { getFocusedRouteNameFromRoute } from '@react-navigation/native';

import LoginScreen from '../LoginScreen'
import PasswordScreen from '../PasswordScreen'
import HomeScreen from '../HomeScreen'


const Stack = createStackNavigator()
const Drawer = createDrawerNavigator()
const sideMenuDisabledScreens = ['Login', 'Password']

const DrawerNavigator = () => {
  return (
    <Drawer.Navigator 
      screenOptions={{headerShown: false}} 
      drawerPosition="right"
      drawerContent={(props) => <SideMenu {...props} />}
    >
    <Drawer.Screen 
      name="Initial"
      component={StackNavigator}
      options={({ route }) => {
        const routeName = getFocusedRouteNameFromRoute(route) ?? 'Login'
        if (sideMenuDisabledScreens.includes(routeName))
            return ({swipeEnabled: false})
      }} 
    />
    </Drawer.Navigator>
  );
}

const StackNavigator = () => {
  return (
    <Stack.Navigator screenOptions={{headerShown: false}}>
      <Stack.Screen name='Login' component={LoginScreen}/>
      <Stack.Screen name='Password' component={PasswordScreen} options={{gestureEnabled: false}}/>
      <Stack.Screen name='Home' component={HomeScreen} />
    </Stack.Navigator>
  );
}

function MainNavigator() {
  return (
    <NavigationContainer>
      <DrawerNavigator />
    </NavigationContainer>
  );
}

export default MainNavigator
  

App.js содержит следующий код

 import React, { Component } from 'react';
import MainStackNavigator from './src/navigation/MainStackNavigator';

export default class App extends Component {

  render() {
    return (
      <>
        <MainStackNavigator />
        </>
    );
  }
}
  

Комментарии:

1. это было именно то, что мне было нужно, и это сработало! Спасибо!

Ответ №6:

swipeEnabled Свойство может помочь, но ящик все равно может быть запущен по другим причинам (например, действие может открыть его программно).

Если вы хотите убедиться, что в некоторых случаях ящик вообще не отображается, и вы можете определить условие глобально, вы можете использовать drawerStyle: { display: 'none' } в screenOptions :

 const screenOptions = {
    drawerStyle: {
        display: 'none',
    },
    // ...
};

<Drawer.Navigator
    drawerContent={({ navigation }) => (
        <DrawerContent navigation={navigation} />
    )}
    screenOptions={screenOptions}
>
    {'...'}
</Drawer.Navigator>
  

В моем случае я не хочу показывать ящик, если пользователь не аутентифицирован, поэтому я определяю отображение: ‘none’ в этом случае.