2

I have a bottom tab with buttons A,B,C,D,E.

  • When I'm on screen A I want the tab to show B,C,D,E buttons but not button A.
  • When I'm on screen B I want the tab to show A,C,D,E buttons but not button B.
  • When I'm on other screens I want to show A,C,D,E buttons or B,C,D,E (depends witch I pick A or B).

I have searched all over google, stackoverflow, youtube and have not seen a solution to this need.

  • I'm using react navigation v5.

I have tried in many ways and somethings like this:

<Tab.Screen name="A" component={A}
   options={
     ()=>{
       tabBarButton:(props)=>{
         if(isScreen("A")){
            return null;
         }else{
            return <TouchableOpacity {...props}/>
         }
       }     
     }
   }
/>

<Tab.Screen name="B" component={B}
   options={
     ()=>{
       tabBarButton:(props)=>{
         if(isScreen("A")){
            return <TouchableOpacity {...props}/>
         }else{
            return null;
         }
       }     
     }
   }
/>

But this gives me not the correct behavior even though it does not error out!!

If you guys do not understand the problem let me know and i will make the problem more concrete.

If you do not have time to explain the solution at least give me a code sample or an article or something for this use case.

PLZ HELP.

2 Answers2

1

You will have to create a custom tab bar for this and conditionally show the labels.

You can see the reference for the custom tab bar here https://reactnavigation.org/docs/bottom-tab-navigator/#tabbar

You will have to create something like below (I have modified the sample code from the documentation)

function MyTabBar({ state, descriptors, navigation }) {

  //Condition to decide the tab or not
  const shouldDisplay = (label, isFocused) => {
    if (label === 'A' && isFocused) return false;
    else if (label === 'B' && isFocused) return false;
    else return true;
  };

  return (
    <View style={{ flexDirection: 'row' }}>
      {state.routes.map((route, index) => {
        const { options } = descriptors[route.key];
        const label =
          options.tabBarLabel !== undefined
            ? options.tabBarLabel
            : options.title !== undefined
            ? options.title
            : route.name;

        const isFocused = state.index === index;

        if (!shouldDisplay(label, isFocused)) return null;

        const onPress = () => {
          const event = navigation.emit({
            type: 'tabPress',
            target: route.key,
          });

          if (!isFocused && !event.defaultPrevented) {
            navigation.navigate(route.name);
          }
        };

        const onLongPress = () => {
          navigation.emit({
            type: 'tabLongPress',
            target: route.key,
          });
        };

        return (
          <TouchableOpacity
            accessibilityRole="button"
            accessibilityState={isFocused ? { selected: true } : {}}
            accessibilityLabel={options.tabBarAccessibilityLabel}
            testID={options.tabBarTestID}
            onPress={onPress}
            onLongPress={onLongPress}
            style={{ flex: 1 }}>
            <Text style={{ color: isFocused ? '#673ab7' : '#222' }}>
              {label}
            </Text>
          </TouchableOpacity>
        );
      })}
    </View>
  );
}

You can see the code in the below snack https://snack.expo.io/@guruparan/customtabs

Guruparan Giritharan
  • 15,660
  • 4
  • 27
  • 50
0

It's is recommended to develop a shared common component for bottom navigation (with different params to control how many buttons and where to go). And you put the bottom navigation in each page.

This case, each page has its customized navigation bottom display.

Xin
  • 33,823
  • 14
  • 84
  • 85