Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

There's no way to hide the tabBar as you can in react navigation #518

Closed
tylerthedeveloper opened this issue Apr 24, 2023 · 23 comments
Closed

Comments

@tylerthedeveloper
Copy link

Which package manager are you using? (Yarn is recommended)

None

Summary

The tabBar option wasn't ported over so there is no good way to hide the tabBar

Minimal reproducible example

n/a - this is easy to do in react navigation

@QuesoCaliente
Copy link

did you find any solution to hide tabs? The documentation specifies that you can hide a tab by adding the href property as null in the options of the tabs.Screen.

@fuelkoy
Copy link

fuelkoy commented Apr 26, 2023

Hide tabBar for some screens:

<Tabs
      screenOptions={({ route }) => ({
        tabBarStyle: {
          display: route.name === 'example' ? 'none' : 'flex',
        },
      })}
    >
      <Tabs.Screen name="index" />
      <Tabs.Screen name="(root)" options={{ href: null, }} />
</Tabs>

@QuesoCaliente was mentioning this: https://expo.github.io/router/docs/guides/tabs/, and it is shown above: (root) tab/ tabIcon would not be shown in tab bar

@tylerthedeveloper
Copy link
Author

tylerthedeveloper commented Apr 29, 2023

@QuesoCaliente yes I see how to hide a page itself, that’s not the problem, I wanted to automatically hide the tab bar when pushing a new page on the stack

this worked well before expo-router

Ill try this - I don’t know if this goes in a different issue but likewise when I have this stack navigators in the stack and push it duplicates the header and the back button isn’t propagated up to the top Nav bar, but this works out of the box in react navigation

Main Stack

  • tabNavigator
  • tab 1 = stack

When I push a page on top of the stack in tab 1 stack it goes inside the navigator and thus duplicates the header, I know I can hide the hide on one or the other but then every page will require conditional logic, whereas I just want the pushed page to be on top, ideally both without the tab bar and with its header, which would have the correct title and back button

Please let me know if you want to make a different issue but I think these are interrelated

@marklawlor
Copy link
Contributor

You can achieve this by using the same structure described in React Navigation Docs https://reactnavigation.org/docs/hiding-tabbar-in-screens/, simply nest your Tab layout inside the Stack layout.

app/
├── (tabs)/
│   ├── _layout.tsx // Uses <Tabs />
│   ├── index.tsx
│   ├── tab2.tsx
│   └── tab3.tsx
├── _layout.tsx // Uses <Stack />
├── routeWithoutTabs.tsx
└── secondRouteWithoutTabs.tsx

@MZ-2406
Copy link

MZ-2406 commented Aug 1, 2023

I made it work using this:

<Tabs
      screenOptions={{
        tabBarStyle: {
          display: usePathname() === 'example' ? 'none' : 'flex',
        },
      }}
    >
      <Tabs.Screen name="index" />
      <Tabs.Screen name="(root)" options={{ href: null, }} />
</Tabs>

@alexandreaugus
Copy link

I can't get this to work. Have anyone had success?

usePathname changes during re-render but the last result is the main tab, not the child one

@leonardobelilomessias
Copy link

its works to me .
<Tabs.Screen
name="example"
options={{
title:"Example",
tabBarButton:()=>null
}}

     />

@dhatGuy
Copy link

dhatGuy commented Sep 24, 2023

I use this to hide tab bar

  const segments = useSegments();

  // if screen is in the home or live stack, hide the tab bar
  const hide = segments.includes("home") || segments.includes("live")
    
   <Tabs
      screenOptions={{
        tabBarStyle: {
          display: hide ? "none" : "flex",
        },
      }}
    >
    ...
 </Tabs>

@CHVrolledout
Copy link

CHVrolledout commented Oct 10, 2023

can you please explain to me? how do you achieve this

@Ortbri
Copy link

Ortbri commented Oct 30, 2023

I use this to hide tab bar

  const segments = useSegments();

  // if screen is in the home or live stack, hide the tab bar
  const hide = segments.includes("home") || segments.includes("live")
    
   <Tabs
      screenOptions={{
        tabBarStyle: {
          display: hide ? "none" : "flex",
        },
      }}
    >
    ...
 </Tabs>

This works, its a bit buggy. The Tab bar leaves when going into the nested screen as it should, but the background seems to stay sometimes interrupting the view.

@JuanRdBO
Copy link

JuanRdBO commented Nov 7, 2023

I would really appreciate a hook like the one in react-navigation where you can simply do:

navigation.setOptions({ tabBarVisible: false });

@felipemenezes98
Copy link

is there an official solution for that?

@Lurtroxx
Copy link

Any updates on this? It should not be closed, the issue is not resolved.

@hicodify
Copy link

There are some workarounds as mentioned above, however, I consider that the ideal solution would be something like the one implemented in react navigation, this should definitely not be marked as closed.

navigation.setOptions({ tabBarVisible: false })

@Retwix
Copy link

Retwix commented Jan 16, 2024

Still looking for a proper solution 👀

@Abdalrzakalsouki
Copy link

Abdalrzakalsouki commented Jan 24, 2024

It appear that the only soultion is to hide the tab bar based on state and update that state (if we want to hide it dynamicly) from the target place based on a context or gloabl state library. I think this is not making sense because it is a lot of work and complexity for a simple task. There is should be a hook similar to react navigation. All the previous comments suggest to hide it staticlty on certine page but what if we want to do that dynamicly

@mleister97
Copy link

mleister97 commented Jan 24, 2024

I made it work using this:

<Tabs
      screenOptions={{
        tabBarStyle: {
          display: usePathname() === 'example' ? 'none' : 'flex',
        },
      }}
    >
      <Tabs.Screen name="index" />
      <Tabs.Screen name="(root)" options={{ href: null, }} />
</Tabs>

Is this the recommended approach for implementing nested stack navigators inside tab bars? It seems to re-render the entire router whenever the pathname changes. While it may not be optimal, is there anyone who can please confirm whether this is the correct solution?

This is working for me on Android & iOS. If you have troubles on iOS with blank space use:

// App.js
import { enableScreens } from 'react-native-screens';

// Added following on the first line of useEffect
enableScreens(false);

See here: react-navigation/react-navigation#10432

Please reopen this issue.

@animaonline
Copy link

It needs to be done using an imperative way, let's say you have a screen where the user can enter full screen by tapping the screen twice.

@enkay
Copy link

enkay commented Apr 17, 2024

I use this to hide tab bar

  const segments = useSegments();

  // if screen is in the home or live stack, hide the tab bar
  const hide = segments.includes("home") || segments.includes("live")
    
   <Tabs
      screenOptions={{
        tabBarStyle: {
          display: hide ? "none" : "flex",
        },
      }}
    >
    ...
 </Tabs>

This works, but when returning to a route with the tab bar visible, the tab bar takes a second to reappear.

Is there a cleaner way to do it?

@cardiscardis
Copy link

const segments = useSegments();

// should this be used for typescript?
const hide = segments.includes("home" as never) || segments.includes("live" as never)

<Tabs
screenOptions={{
tabBarStyle: {
display: hide ? "none" : "flex",
},
}}
>
...

@AlfredMan
Copy link

While this works, it still leaves a blank empty space at the bottom
<Tabs
screenOptions={{
tabBarStyle: {
display: hide ? "none" : "flex",
},
}}

The code from @mleister97 doesn't seems to get rid of the blank space originally ocuppied by the tabbar
// App.js
import { enableScreens } from 'react-native-screens';
// Added following on the first line of useEffect
enableScreens(false);

Tried to set height too from the 'setHidden' flag but that also doesn't work
<Tabs
screenOptions={{
tabBarStyle: {
display: hide ? "none" : "flex",
},
}}

@presedo93
Copy link

At least in my case it seems that the display: hide ? "none" : "flex" solution works, but partially... When you enter one of the screens that should have it hidden it shows the blank area corresponding to the tab bar. But if I put the app in background and open again, it correctly hides the tab bar.

Looks like it needs some more renders to achieve it?

@fmmattioni
Copy link

<Tabs.Screen
        name="index"
        options={{
          tabBarItemStyle: {
            display: 'none',
          },
        }}
/>

worked for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests