web-dev-qa-db-fra.com

React Navigation comment masquer la barre d'onglets de la navigation dans la pile

J'ai la navigation et les écrans de pile suivants:

export const HomeStack = createStackNavigator({
    Home: HomeScreen,
    Categories: CategoriesScreen,
    Products: ProductsScreen,
    ProductDetails: ProductDetailsScreen,
})

Je souhaite masquer les onglets uniquement dans ProductDetailsScreen

export const hideTabBarComponents = [
    'ProductDetails',
]

export const MainTabs = createBottomTabNavigator(
    {
        Home: HomeStack,
        Favorite: FavoriteScreen,
        Account: AccountScreen,
        Help: HelpScreen,
        Events: EventsScreen
    },
    {
        navigationOptions: ({ navigation }) => ({

            tabBarIcon: ({ focused, tintColor }) => {
                ...
            },
            tabBarLabel: ({ focused, tintColor }) => {
                ...
            },

            tabBarVisible: ! hideTabBarComponents.includes(navigation.state.routeName)

        }),
    }
);

Le problème qui ne peut transmettre aucune option à la navigation par onglets à partir de la navigation par pile

Tous les écrans de pile ne sont pas tous un seul

7
Ahmad Alselwadi

Après une petite recherche, le code suivant a résolu le problème:

HomeStack.navigationOptions = ({ navigation }) => {

    let tabBarVisible = true;

    let routeName = navigation.state.routes[navigation.state.index].routeName

    if ( routeName == 'ProductDetails' ) {
        tabBarVisible = false
    }

    return {
        tabBarVisible,
    }
}
7
Ahmad Alselwadi

Pour React Navigation 5, vous pouvez le faire à l'intérieur du composant de pile:

props.navigation.dangerouslyGetParent().setOptions({
  tabBarVisible: false
});

https://reactnavigation.org/docs/en/navigation-prop.html#setoptions---update-screen-options-from-the-component

Soyez prudent avec cette utilisation, vous voudrez réinitialiser tabBarVisible à true une fois le composant démonté.

Par exemple, avec React hooks à l'intérieur du composant Stack:

    useEffect(() => {
      const parent = props.navigation.dangerouslyGetParent();
      parent.setOptions({
        tabBarVisible: false
      });
      return () =>
        parent.setOptions({
          tabBarVisible: true
        });
    }, []);

Ou vous pouvez réinitialiser la tabBarVisible dans le composant Stack.Screen avec le bouton de retour en appuyant comme ceci:

    const StackNav = (props) => (
      <Stack.Screen
        name='name'
        component={Name}
        options={{
          headerTitle: 'Name',
          headerLeft: () => (
            <Text
              onPress={() =>
                props.navigation.setOptions({
                tabBarVisible: true
                })
              }
            >
              on back
            </Text>
          )
        }}
      />
    }

(La deuxième approche fonctionne mieux.)

2
Jordan Daniels

C'est comme ça que je l'ai fait. Sélectionnez la pile dans laquelle vous souhaitez masquer la barre d'onglets. Vous pouvez le sélectionner en fonction de l'index.

AppStack.navigationOptions = ({ navigation }) => {
  let tabBarVisible = true;
    if (navigation.state.index > 0) {
       tabBarVisible = false;
    }
    return {
       tabBarVisible
    };
};

Voici le lien de la docs of React navigation

0
Pratap Sharma

C'est la solution que j'ai utilisée dans mon projet.

J'ai un navigateur en bas de l'onglet, avec 2 itinéraires: Accueil et Profil. La route ProfileHomePage apporte à une pile de navigation ProfileStackNavigation.

Ensuite, dans ProfileStackNavigation, j'ai le ProfileHomePage où l'onglet inférieur devrait apparaître, et d'autres pages enfants, où les onglets inférieurs ne devraient pas être visibles. J'ai ajouté un paramètre tabBarVisible: false dans ces pages.

Enfin, dans l'itinéraire MainTabNavigator ProfileHomePage, j'ai ajouté la fonction navigationOptions, pour tester si l'itinéraire actuel a le paramètre tabBarVisible.

const ProfileStackNavigation = createStackNavigator(
  {
    ProfileHomePage: ProfileHomePage,
    AboutAppPage: {screen: AboutAppPage, params: {tabBarVisible: false}},
    DiaryPage: {screen: DiaryPage, params: {tabBarVisible: false}},
    FilesPage: {screen: FilesPage, params: {tabBarVisible: false}},
    NotificationsPage: {screen: NotificationsPage, params: {tabBarVisible: false}},
  },
  {
    initialRouteName: 'ProfileHomePage',
  },
);

const MainTabNavigator = createBottomTabNavigator(
  {
    HomePage: HomePage,
    ProfileHomePage: {
      screen: ProfileStackNavigation,
      navigationOptions: ({ navigation }) => {
        const {params = {}} = navigation.state.routes[navigation.state.index];
        const tabBarVisible = params.tabBarVisible === false ? params.tabBarVisible : true;
        return {
          tabBarVisible,
        }
      }
    },
  },
  {
    initialRouteName: 'HomePage',
    tabBarComponent: props => <AppFooterTab {...props} />,
  },
);
0
Marcelo Souza