Search code examples
react-nativereact-navigation-v6

How can I fix my navigation stacks so bottom tab shows in all screens expect auth?


I have been changing color of my bottom tab which I managed to by switching some stack places in my navigation. Switched HomeTab where homescreen was previously HomeScreen and moved homeScreen to drawer stack. But now my issue is that in Homestack all other screens doesn't have bottom tabs. I would like to have bottom tabs available on all screens expect auth ones. Also the image should be only shown in the homescreen. I tried adding it to drawer but it makes the image disappear. Also the tabbar title's are not showing in the top. (homescreen doesn't need title)

import React, { useEffect } from 'react'
import { Pressable, View, Image, Platform } from 'react-native'
// Navigation
import {
  DrawerActions,
  getFocusedRouteNameFromRoute,
  useNavigation,
  useRoute,
} from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
import {
  createBottomTabNavigator,
  BottomTabBar,
} from '@react-navigation/bottom-tabs'
import { createDrawerNavigator } from '@react-navigation/drawer'
//import { SafeAreaView } from 'react-native-safe-area-context'
import { useSelector } from 'react-redux'
// Icons
import Ionicons from 'react-native-vector-icons/Ionicons'
// Screens
import LoginScreen from '../screens/authentication/login'
import RegisterScreen from '../screens/authentication/register'
import ForgotPasswordScreen from '../screens/authentication/forgotPassword'
import ConfirmScreen from '../screens/authentication/confirmEmail'
import ConfirmNewPassScreen from '../screens/authentication/confirmNewPassword'
import HomeScreen from '../screens/home'
import TrafficNoticesScreen from '../screens/notices/trafficNotices'
import UkkScreen from '../screens/ukk/faq'
import ProfileScreen from '../screens/profile'
import AddNewInsurance from '../screens/profile/addInsurance'
import AddNewCar from '../screens/profile/addCar'
import EditWorkplaceDetails from '../screens/profile/editWorkplaceDetails'
import AccidentsScreen from '../screens/accidents'
import CarAccidentScreen from '../screens/accidents/carAccident'
import PersonalAccidentScreen from '../screens/accidents/personalAccident'
import AssetsAccidentScreen from '../screens/accidents/assetsAccident'
import TrafficAccidentScreen from '../screens/accidents/trafficAccident'
import TowingScreen from '../screens/accidents/towing'
import GlassAccidentScreen from '../screens/accidents/glassAccident'
import RockOnWindowScreen from '../screens/accidents/rockOnWindow'
import CrackOnWindowScreen from '../screens/accidents/crackOnWindow'
import YesGlassInsuranceScreen from '../screens/accidents/yesGlassInsurance'
import NoGlassInsuranceScreen from '../screens/accidents/noGlassInsurance'
import TechnicalIssueScreen from '../screens/accidents/technicalIssue'
import CarBrokenScreen from '../screens/accidents/carBroken'
import BrokenCarTireScreen from '../screens/accidents/brokenCarTire'
import NearestServicesScreen from '../screens/accidents/nearestServices'
import AskOfferScreen from '../screens/offer'
import LocalServicesScreen from '../screens/services/localServices'
import ServicesScreen from '../screens/services/services'
import AdsScreen from '../screens/ads'
import NoticesScreen from '../screens/notices'
import Notices from '../screens/notices/notices'
import InsuranceCompaniesScreen from '../screens/insurances'
import Info from '../screens/info'
import Settings from '../screens/settings/settings'
import OnBoardingScreen from '../screens/onboarding'
import DrawerMenu from '../navigation/Drawer'
// Colors
import colors from '../styles/Colors'

// Main tab navigation
const Tab = createBottomTabNavigator()

const CustomBottomTab = (props) => {
  return <BottomTabBar {...props} />
}

const HomeTab = () => {
  return (
    <Tab.Navigator
      tabBar={(props) => <CustomBottomTab {...props} />}
      screenOptions={({ route }) => ({
        tabBarIcon: ({ focused, color, size }) => {
          let iconName

          if (route.name === 'Koti') {
            iconName = focused ? 'ios-home' : 'ios-home-outline'
          } else if (route.name === 'Palvelut') {
            iconName = focused ? 'ios-pin' : 'ios-pin-outline'
          } else if (route.name === 'Ukk') {
            iconName = focused ? 'ios-help-circle' : 'ios-help-circle-outline'
          } else if (route.name === 'Omat tiedot') {
            iconName = focused
              ? 'ios-person-circle'
              : 'ios-person-circle-outline'
          }
          // You can return any component that you like here!
          return <Ionicons name={iconName} size={size} color={color} />
        },
        tabBarActiveTintColor: colors.white_087,
        tabBarInactiveTintColor: colors.gray_066,
        tabBarActiveBackgroundColor: colors.black_021,
        tabBarStyle: {
          display: 'flex',
          backgroundColor: colors.black_015,
          borderTopColor: colors.black_015,
        },
        tabBarHideOnKeyboard: true,
        headerShown: false,
        headerTransparent: false,
        headerTitleAlign: 'center',
        headerTitleStyle: { color: colors.black, fontSize: 16 },
        // headerRight: () => (
        //   <>
        //     <Pressable
        //       onPress={() => navigation.dispatch(DrawerActions.openDrawer())}
        //     >
        //       <Ionicons
        //         testID='DrawerMenu'
        //         name='ellipsis-horizontal-outline'
        //         size={40}
        //         color={colors.black}
        //       />
        //     </Pressable>
        //   </>
        // ),
      })}
    >
      <Tab.Screen
        name='Koti'
        component={HomeScreen}
        options={{
          headerTitle: 'Vahingonsattuessa',
          headerShown: false,
        }}
      />
      <Tab.Screen
        name='Palvelut'
        component={LocalServicesScreen}
        options={{
          headerTitle: 'Palvelut',
          headerTitleStyle: { color: colors.white_087 },
          headerBackgroundContainerStyle: { backgroundColor: colors.black_015 },
        }}
      />
      <Tab.Screen
        name='Ukk'
        component={UkkScreen}
        options={{
          headerBackgroundContainerStyle: { backgroundColor: colors.white },
          headerTitle: 'Usein kysytyt kysymykset',
        }}
      />
      <Tab.Screen
        name='Omat tiedot'
        component={ProfileStack}
        options={{ headerShown: false }}
      />
    </Tab.Navigator>
  )
}

const Drawer = createDrawerNavigator()

const DrawerNav = () => {
  const completed = useSelector((state) => state.boardingReducer.completed)

  return completed === false ? (
    <BoardingStack />
  ) : (
    <Drawer.Navigator
      drawerContent={(props) => <DrawerMenu {...props} />}
      screenOptions={{
        headerShown: false,
        drawerStyle: { backgroundColor: colors.black_007 },
      }}
    >
      <Drawer.Screen name='HomeTab' component={HomeStack} />
    </Drawer.Navigator>
  )
}

const Boarding = createNativeStackNavigator()

const BoardingStack = () => {
  return (
    <Boarding.Navigator>
      <Boarding.Screen
        name='Boarding'
        component={OnBoardingScreen}
        options={{ headerShown: false }}
      />
    </Boarding.Navigator>
  )
}

const Home = createNativeStackNavigator()

const HomeStack = () => {

  return (
    <Home.Navigator
      screenOptions={({ navigation, route }) => {
        return {
          animationEnabled: false,
          headerBackTitleVisible: false,
          headerTintColor: colors.gray_066,
          headerTitleAlign: 'center',
          headerTitleStyle: {
            color: colors.white_087,
            fontSize: 16,
          },
          headerTransparent: false,
          headerStyle: { backgroundColor: colors.black_015 },
          headerLeft: () => {
            if (route.name == 'Koti') {
              return  <Image
              resizeMode='contain'
              style={{
                width: 200,
                height: Platform.OS == 'ios' ? 35 : 50,
                alignSelf: 'center',
                marginLeft: Platform.OS == 'ios' ? -40 : 0,
              }}
              source={require('../images/vh_logo_neg.png')}
            />
            }
          },
          headerRight: () => (
            <>
              <Pressable
                onPress={() => navigation.dispatch(DrawerActions.openDrawer())}
              >
                <Ionicons
                  testID='DrawerMenu'
                  name='ellipsis-horizontal-outline'
                  size={40}
                  color={colors.gray_066}
                />
              </Pressable>
            </>
          ),
        }
      }}
    >
      <Home.Screen
        name='HomeScreen'
        component={HomeTab}
        options={{
          headerTitle: '',
          headerShadowVisible: false,
        }}
      />
      <Home.Screen name='Vahinkopalvelut' component={AccidentsScreen} />
      <Home.Screen
        name='Ajoneuvovahinko / vika'
        component={CarAccidentScreen}
      />
      <Home.Screen name='Henkilövahinko' component={PersonalAccidentScreen} />
      <Home.Screen name='Omaisuusvahinko' component={AssetsAccidentScreen} />
      <Home.Screen
        name='Liikennevahinko / muu vahinko'
        component={TrafficAccidentScreen}
      />
      <Home.Screen name='Hinaus' component={TowingScreen} />
      <Home.Screen name='Lasivahinko' component={GlassAccidentScreen} />
      <Home.Screen
        name='Tuulilasiin tuli kivi / nasta'
        component={RockOnWindowScreen}
      />
      <Home.Screen
        name='Tuulilasissa on halkeama'
        component={CrackOnWindowScreen}
      />
      <Home.Screen
        name='Lasivakuutus kyllä'
        component={YesGlassInsuranceScreen}
      />
      <Home.Screen name='Lasivakuutus ei' component={NoGlassInsuranceScreen} />
      <Home.Screen name='Tekninenvika' component={TechnicalIssueScreen} />
      <Home.Screen name='Tekninen vika' component={CarBrokenScreen} />
      <Home.Screen name='Huoltokorjaamot' component={NearestServicesScreen} />
      <Home.Screen name='Rengas rikko' component={BrokenCarTireScreen} />
      <Home.Screen
        name='Rengas rikki ei hinausta'
        component={NearestServicesScreen}
        options={{
          headerTitle: 'Rengasliikkeet',
        }}
      />
      <Home.Screen name='Määräaikaishuolto' component={NearestServicesScreen} />
      <Home.Screen name='Pyydä tarjous' component={AskOfferScreen} />
      <Home.Screen
        name='Paikalliset palvelut'
        component={LocalServicesScreen}
      />
      <Home.Screen name='Ajoneuvopalvelut' component={ServicesScreen} />
      <Home.Screen name='Henkilöpalvelut' component={ServicesScreen} />
      <Home.Screen name='Omaisuuspalvelut' component={ServicesScreen} />
      <Home.Screen name='Tarjoukset' component={AdsScreen} />
      <Home.Screen name='Tiedotteet' component={NoticesScreen} />
      <Home.Screen name='Muut Tiedotteet' component={Notices} />
      <Home.Screen name='Liikennetiedotteet' component={TrafficNoticesScreen} />
      <Home.Screen name='Info' component={Info} />
      <Home.Screen
        name='Vakuutus yhtiöt'
        component={InsuranceCompaniesScreen}
      />
      <Home.Screen
        name='Asetukset'
        component={Settings}
        options={{
          headerTitleStyle: { color: colors.white_087, fontSize: 20 },
          headerStyle: { backgroundColor: colors.black_015 },
          headerRight: () => <View />,
        }}
      />
      <Home.Screen
        name='Kirjaudu'
        component={LoginScreen}
        options={{
          headerTitleStyle: { color: colors.white_087, fontSize: 20 },
          headerStyle: { backgroundColor: colors.black_015 },
          headerTintColor: colors.gray_066,
          headerRight: () => <View />,
        }}
      />
      <Home.Screen
        name='Rekisteröidy'
        component={RegisterScreen}
        options={{
          headerTitleStyle: { color: colors.white_087, fontSize: 20 },
          headerStyle: { backgroundColor: colors.black_015 },
          headerTintColor: colors.gray_066,
          headerRight: () => <View />,
        }}
      />
      <Home.Screen
        name='Resetoi salasana'
        component={ForgotPasswordScreen}
        options={{
          headerTitleStyle: { color: colors.white_087, fontSize: 20 },
          headerStyle: { backgroundColor: colors.black_015 },
          headerTintColor: colors.gray_066,
          headerRight: () => <View />,
        }}
      />
      <Home.Screen
        name='Vahvista tili'
        component={ConfirmScreen}
        options={{
          headerTitleStyle: { color: colors.white_087, fontSize: 20 },
          headerStyle: { backgroundColor: colors.black_015 },
          headerTintColor: colors.gray_066,
          headerRight: () => <View />,
        }}
      />
      <Home.Screen
        name='Vaihda salasana'
        component={ConfirmNewPassScreen}
        options={{
          headerTitleStyle: { color: colors.gray_066, fontSize: 20 },
          headerStyle: { backgroundColor: colors.black_015 },
          headerTintColor: colors.gray_066,
          headerRight: () => <View />,
        }}
      />
    </Home.Navigator>
  )
}

const Profile = createNativeStackNavigator()
const ProfileStack = () => {
  const navigation = useNavigation()
  const route = useRoute()

  useEffect(() => {
    const tabHiddenRoutes = [
      'Asetukset',
      'Kirjaudu',
      'Rekisteröidy',
      'Resetoi salasana',
      'Vahvista tili',
      'Vaihda salasana',
    ]

    if (tabHiddenRoutes.includes(getFocusedRouteNameFromRoute(route))) {
      navigation.setOptions({ tabBarStyle: { display: 'none' } })
    } else {
      navigation.setOptions({ tabBarStyle: { display: 'flex' } })
    }
  }, [navigation, route])

  return (
    <Profile.Navigator>
      <Profile.Screen
        name='Omat Tiedot'
        component={ProfileScreen}
        options={{
          headerTitle: 'Omat tiedot',
          headerTitleAlign: 'center',
          headerShadowVisible: false,
          headerTransparent: false,
          headerTitleStyle: { color: colors.black, fontSize: 16 },
          headerRight: () => (
            <>
              <Pressable
                onPress={() => navigation.dispatch(DrawerActions.openDrawer())}
              >
                <Ionicons
                  testID='DrawerMenu'
                  name='ellipsis-horizontal-outline'
                  size={40}
                  color={colors.black}
                />
              </Pressable>
            </>
          ),
        }}
      />
      <Profile.Screen
        name='Lisää vakuutus'
        component={AddNewInsurance}
        options={{
          headerLeft: null,
          headerRight: null,
          headerBackTitle: 'Lisää vakuutus',
          headerTitleAlign: 'center',
          headerShadowVisible: false,
        }}
      />
      <Profile.Screen
        name='Lisää ajoneuvo'
        component={AddNewCar}
        options={{
          headerLeft: null,
          headerRight: null,
          headerBackTitle: 'Lisää ajoneuvo',
          headerTitleAlign: 'center',
          headerShadowVisible: false,
        }}
      />
      <Profile.Screen
        name='Työpaikka tiedot'
        component={EditWorkplaceDetails}
        options={{
          headerLeft: null,
          headerRight: null,
          headerBackTitle: 'Työpaikka tiedot',
          headerTitleAlign: 'center',
          headerShadowVisible: false,
        }}
      />
    </Profile.Navigator>
  )
}

// Root navigation stack that includes tab navigation after you are signed/registered in
const Root = createNativeStackNavigator()

const Navigation = () => {
  return (
    <Root.Navigator
      screenOptions={() => {
        return {
          headerTitleAlign: 'center',
        }
      }}
    >
      <Root.Screen
        name='Vahginonsattuessa'
        component={DrawerNav}
        options={() => {
          return {
            headerShown: false,
            headerStyle: {
              backgroundColor: colors.white,
              shadowColor: 'transparent',
            },
          }
        }}
      />
    </Root.Navigator>
  )
}

export default Navigation


Solution

  • You can create a stack and put it inside the tab navigator.

    For eg:

    import { createStackNavigator } from '@react-navigation/stack';
    
    const Stack = createStackNavigator();
    
    function MyStack() {
      return (
        <Stack.Navigator>
          <Stack.Screen name="Home" component={Home} />
          <Stack.Screen name="Profile" component={Profile} />
          <Stack.Screen name="Settings" component={Settings} />
        </Stack.Navigator>
      );
    }
    
    import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
    
    const Tab = createBottomTabNavigator();
    
    function MyTabs() {
      return (
        <Tab.Navigator>
          <Tab.Screen name="Home" component={MyStack} /> // Register the stack
          <Tab.Screen name="Settings" component={SettingsScreen} />
        </Tab.Navigator>
      );
    }