samw2k00
samw2k00

Reputation: 300

React-Navigation hide tabBar in StackNavigator inside a TabRouter

Having problem hiding the tabBar once we are inside StackNavigator which is inside TabRouter.

im using the navigatorOption, but it does not seem to be doing anything.

navigationOptions: {tabBarVisible: false}

can access expo.io from https://snack.expo.io/Sk4fQHAfZ

import React from 'react';
import {
  Button,
  Platform,
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import {
  createNavigator,
  createNavigationContainer,
  TabRouter,
  addNavigationHelpers,
  StackNavigator,
} from 'react-navigation';

const MyNavScreen = ({ navigation, banner }) => (
  <ScrollView>
    <Text>{banner}</Text>
    <Button
      onPress={() => {
        navigation.goBack(null);
      }}
      title="Go back"
    />
  </ScrollView>
);

const NestedMyNavScreen = ({ navigation, banner }) => (
  <ScrollView>
    <Text>{banner}</Text>
    <Button
      onPress={() => navigation.navigate('Profile', { name: 'Jane' })}
      title="Go to a profile screen"
    />
    <Button
      onPress={() => navigation.navigate('Photos', { name: 'Jane' })}
      title="Go to a photos screen"
    />
  </ScrollView>
);

const MyNotificationsScreen = ({ navigation }) => (
  <MyNavScreen banner="Notifications Screen" navigation={navigation} />
);

const MySettingsScreen = ({ navigation }) => (
  <MyNavScreen banner="Settings Screen" navigation={navigation} />
);

const MyPhotosScreen = ({ navigation }) => {
  let params = navigation.state.routes[navigation.state.index].params;
  // let params = navigation.state.params;
  return <MyNavScreen
    banner={`${params.name}'s Photos`}
    navigation={navigation}
  />
};
MyPhotosScreen.navigationOptions = {
  title: 'Photos',
};

const MyProfileScreen = ({ navigation }) => {
  let params = navigation.state.routes[navigation.state.index].params;
  // let params = navigation.state.params;
  return <MyNavScreen
    banner={`${params.mode === 'edit' ? 'Now Editing ' : ''}${params.name}'s Profile`}
    navigation={navigation}
  />
};

const CustomTabBar = ({ navigation }) => {
  const { routes } = navigation.state;
  return (
    <View style={styles.tabContainer}>
      {routes.map(route => (
        <TouchableOpacity
          onPress={() => navigation.navigate(route.routeName)}
          style={styles.tab}
          key={route.routeName}
        >
          <Text>{route.routeName}</Text>
        </TouchableOpacity>
      ))}
    </View>
  );
};

const SimpleStack = StackNavigator({
  NestedHome: {
    screen: NestedMyNavScreen
  },
  Profile: {
    path: 'people/:name',
    screen: MyProfileScreen,
    navigationOptions: {tabBarVisible: false}
  },
  Photos: {
    path: 'photos/:name',
    screen: MyPhotosScreen,
  },
});

const CustomTabView = ({ router, navigation }) => {
  const { routes, index } = navigation.state;
  const ActiveScreen = router.getComponentForState(navigation.state);
  return (
    <View style={styles.container}>
      <ActiveScreen
        navigation={addNavigationHelpers({
          ...navigation,
          state: routes[index],
        })}
      />
      <CustomTabBar navigation={navigation} />
    </View>
  );
};

const CustomTabRouter = TabRouter(
  {
    Home: {
      screen: SimpleStack,
      path: '',
    },
    Notifications: {
      screen: MyNotificationsScreen,
      path: 'notifications',
    },
    Settings: {
      screen: MySettingsScreen,
      path: 'settings',
    },
  },
  {
    // Change this to start on a different tab
    initialRouteName: 'Home',
  }
);

const CustomTabs = createNavigationContainer(
  createNavigator(CustomTabRouter)(CustomTabView)
);

const styles = StyleSheet.create({
  container: {
    marginTop: Platform.OS === 'ios' ? 20 : 0,
    flexDirection: 'column',
    justifyContent: 'space-between',
    flex: 1
  },
  tabContainer: {
    flexDirection: 'row',
    height: 48,
  },
  tab: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    margin: 4,
    borderWidth: 1,
    borderColor: '#ddd',
    borderRadius: 4,
  },
});

export default CustomTabs;

Upvotes: 3

Views: 3311

Answers (2)

Ollie
Ollie

Reputation: 664

The problem is that you can only set navigation options for the navigator that renders a given screen. The screen that you want to hide the tab bar on is rendered by a stacknavigator, which does not have a tabBarVisible navigation option.

This link to the docs explains in more detail:

https://reactnavigation.org/docs/en/navigation-options-resolution.html#a-stack-contains-a-tab-navigator-and-you-want-to-set-the-title-on-the-stack-header

The solution is to set the navigation options in your stackNavigator, which is rendered by the tabNavigator. You can use a function to vary the navigation option per screen. Below is an example from the docs:

https://reactnavigation.org/docs/en/navigation-options-resolution.html#a-stack-contains-a-tab-navigator-and-you-want-to-set-the-title-on-the-stack-header

Here's another simple example:

const HomeStack = createStackNavigator(
  {
    Home: HomeScreen,
    Settings: SettingsScreen
  },
  {
    initialRouteName: "Home",
  }
);

HomeStack.navigationOptions = ({ navigation }) => {
  // get the name of the route
  const { routeName } = navigation.state.routes[navigation.state.index];

  if (routeName === 'Settings'){
    tabBarVisible = false;
  }
  else{
    tabBarVisible = true;
  }
  return {
    tabBarVisible, // this now varies based on screen
    tabBarLabel: "Search", // this is the same for all screens
  };
};

export default createBottomTabNavigator(
  {
    HomeStack,
  })

Upvotes: 0

Varun Nath
Varun Nath

Reputation: 5632

Seems like its not working when your using your custom tabRouter.

I got it to work removing it : https://snack.expo.io/H1NmvXE5b

(Also in your expo link you've wrongly used {tabBar : {visible:false}}

You can try and style your tab bar buttons either in each screen in the navigationOptions

OR

you could do it the way its done here: (Just for example sake from the native-base docs:)

export default MainScreenNavigator = TabNavigator(
  {
    LucyChat: { screen: LucyChat },
    JadeChat: { screen: JadeChat },
    NineChat: { screen: NineChat }
  },
  {
    tabBarPosition: "bottom",
    tabBarComponent: props => {
      return (
        <Footer>
          <FooterTab>
            <Button
              vertical
              active={props.navigationState.index === 0}
              onPress={() => props.navigation.navigate("LucyChat")}>
              <Icon name="bowtie" />
              <Text>Lucy</Text>
            </Button>
            <Button
              vertical
              active={props.navigationState.index === 1}
              onPress={() => props.navigation.navigate("JadeChat")}>
              <Icon name="briefcase" />
              <Text>Nine</Text>
            </Button>
            <Button
              vertical
              active={props.navigationState.index === 2}
              onPress={() => props.navigation.navigate("NineChat")}>
              <Icon name="headset" />
              <Text>Jade</Text>
            </Button>
          </FooterTab>
        </Footer>
      );
    }
  }
));

Upvotes: 1

Related Questions