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

[TabBarIOS] How To Hide Tab Bar in Navigation Interface #1489

Closed
maplebaby opened this issue Jun 2, 2015 · 27 comments
Closed

[TabBarIOS] How To Hide Tab Bar in Navigation Interface #1489

maplebaby opened this issue Jun 2, 2015 · 27 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@maplebaby
Copy link

How To Hide Tab Bar in Navigation Interface

@scyankai
Copy link

scyankai commented Jun 2, 2015

+1

@brentvatne brentvatne changed the title [TabBarIOS]How To Hide Tab Bar in Navigation Interface [TabBarIOS] How To Hide Tab Bar in Navigation Interface Jun 2, 2015
@skyline75489
Copy link

+1.

@wingofshadow
Copy link

I hide the tabbar with toggle the hidden property of the tabbar in tabBarController,but when i swipe back,the animation effect in tabbar disappears.Looking forward to a better hack.

@christopherdro
Copy link
Contributor

You could use Navigator on your index and set the initial route to your TabBars.
Now, any new screen that is pushed will overlap your TabBar screen.

@albertwchang
Copy link

@maplebaby Were you ever able to figure out a solution?

@christopherdro: I'm guessing your proposed solution would mean that ANY scenes pushed onto the stack from that initial route would overlap and cover the tab bar?

@christopherdro
Copy link
Contributor

@Achang28 Yes, in that case any scene will overlap your tab bars.

@feilaoda
Copy link

+1
@christopherdro Can you give a example code? Thanks.

@0517
Copy link

0517 commented Sep 1, 2015

So the final solution is a new design form like above? Any other solution or can someone make it detail about how to achieve the above solution?

@yangaqi
Copy link

yangaqi commented Sep 14, 2015

+10086

@brentvatne
Copy link
Collaborator

You also might want to consider using a JS-based tabbed-navigator, eg: https://github.com/exponentjs/react-native-tab-navigator

@christopherdro
Copy link
Contributor

Here's the sample code.
https://rnplay.org/apps/-P8G_w

@ide @brentvatne Issue can be closed. Example and alternate method provided.

@brentvatne
Copy link
Collaborator

Neat, thanks @christopherdro!

@apaquino
Copy link

Is there an alternative way that doesn't always overlap your tab bar on a new scene?

What is happening to me is that my original login screen doesn't have a tab bar. When a user logs in / signs up, all scenes have a tab bar. When the user logs out, I call this.props.navigator.push to go back to the initial route (which would be the login page) - but it has the tab bar appear on the page, which is not what I want.

@yangaqi
Copy link

yangaqi commented Sep 22, 2015

I add hidesBottomBarWhenPushed in react code but tabbar is not hidden.

so I modify the RCTNavItem code,add a property control tabbar visible, like @Property (nonatomic, assign) BOOL showTabBar;

in RCTNavItemManager.m RCT_EXPORT_VIEW_PROPERTY(showTabBar, BOOL)

and modify the method

  • (void)navigationController:(UINavigationController _)navigationController
    willShowViewController:(__unused UIViewController *)viewController
    animated:(_unused BOOL)animated{
    RCTWrapperViewController * thisController = (RCTWrapperViewController
    )viewController;
    navigationController.tabBarController.tabBar.hidden = !thisController.navItem.showTabBar;
    ...

final add a propType in NavigatorIOS.ios.js

@apaquino
Copy link

@yangaqi Thanks!!!

I'm not using the NavigatorIOS component; I'm using the Navigator component.

Will this solution to the issue need to be changed?

@ide
Copy link
Contributor

ide commented Sep 22, 2015

You could use nested navigators, where the top-level navigator contains two scenes: logged-out and logged-in. The logged-in scene would have a tab bar with a navigator for each tab.

@apaquino
Copy link

@ide thanks. I'll give this a go as well.

@kkgelu
Copy link

kkgelu commented Jan 12, 2016

@christopherdro in the example you provided, if the navigator has a navigation bar, it would be exactly the same navigation bar when switching between tabs. It means I need to somehow change nav bar myself when switching between tabs -- I don't even know it's possible to do so.

Any ideas on handling the nav bar? As I understood, hide/show Nav bar is also not supported...

@Rusya13
Copy link

Rusya13 commented Mar 27, 2016

@yangaqi Thank you! It works!

@rathodmitesh916
Copy link

@yangaqi can you please tell me what is the filename to modify that method ?

@rathodmitesh916
Copy link

Also, anyone has a solution working ?

@mcampsall
Copy link

mcampsall commented Jul 21, 2016

UPDATE: I have it working now for my situation (I wanted 3 tabs to show the tab bar and one of the tabs to hide the tab bar)

@christopherdro The proposed solution above may work in some situations, but is not ideal for what I want to do. I hope someone figures out a way to create a PR for this.

@jainmitesh09 here are the files and edits in the Objective-C code as far as i can make out from @yangaqi 's example:

In Xcode's lefthand sidebar, choose the 'Project Manger' (folder icon) to see the file structure.

The particular folder you are looking for is found at:
[YourAppName] > Libraries > React.xcodeproj > React > Views

RCTNavItem.h

#import "RCTComponent.h"

@interface RCTNavItem : UIView

//add this line:
@property (nonatomic, assign) BOOL showTabBar;

RCTNavItemManager.m

@implementation RCTNavItemManager

RCT_EXPORT_MODULE()

- (UIView *)view
{
  return [RCTNavItem new];
}

// add this line:
RCT_EXPORT_VIEW_PROPERTY(showTabBar, BOOL)

RCTNavigator.m

- (void)navigationController:(UINavigationController *)navigationController
      willShowViewController:(__unused UIViewController *)viewController
                    animated:(__unused BOOL)animated
{

// Add these two lines:
        RCTWrapperViewController *thisController = (RCTWrapperViewController *)viewController;
        navigationController.tabBarController.tabBar.hidden = !thisController.navItem.showTabBar;

I did not need to add propTypes to NavigatorIOS.ios.js or TabBarIOS.ios.js

In order for this all to work, each tab seemingly needs to have its own NavigatorIOS component. When I had the tab simply present a screen the - (void)navigationController:(UINavigationController *)navigationController... method does not get called. This was not an issue for me, because hiding the navBar is easily done with navigationBarHidden: true.

In my case I had a TabNav > HomeNav > HomeScreen

Passing showTabBar prop in HomeNav:

  render() {
    return (
      <NavigatorIOS
        style={styles.container}
        client={this.props.client}
        initialRoute={{
          title: 'Home',
          component: HomeScreen,
          navigationBarHidden: true,
          showTabBar: false,
          passProps: { ...},
        }}/>
      );
    }
  }

I hope this helps someone!

@rathodmitesh916
Copy link

@mcampsall Thank you ! Got another workaround; used Navigator instead NavigatorIOS. But thanks for the solution. Appreciate it. I'll try it out with NavigatorIOS.

@horatiua
Copy link

@jainmitesh09 How did you got this working with Navbar?
Thanks!

@mcampsall
Copy link

@horatiua, the solution i proposed above includes a nav bar (the NavigatorIOS component). Set up a TabBarIOS like normal and just return a NavigatorIOS component in each tab.

Something like this (not tested):

 render() {

    return (
      <TabBarIOS tintColor={SPColors.blue}>

        <TabBarIOS.Item
          selected={this.state.selectedTab === 'home'}
          title='Home'
          icon={require ('./Icons/IconImages/HomeTabIcon.png')}
          onPress={() => {
            this.setState({
              selectedTab: 'home'
            });
          }}>
          <NavigatorIOS
            style={styles.container}
            ref="nav"
            initialRoute={{
              title: 'Home',
              component: HomeNavigationController,
              navigationBarHidden: true,
              showTabBar: false,
              passProps: {
                //pass props here
              },
            }}/>
          </TabBarIOS.Item>


          <TabBarIOS.Item
            selected={this.state.selectedTab === 'secondTab'}
            title='Second Tab'
            icon={require ('./Icons/IconImagesSecondTabIcon.png')}
            onPress={() => this._tabPressed('secondTab')}>
          <NavigatorIOS
            style={styles.container}
            ref="nav"
            initialRoute={{
              title: 'SecondTab',
              component: SecondTabComponent,
              navigationBarHidden: false,
              showTabBar: true,
              passProps: {
                //pass props here
              },
            }}/>
          </TabBarIOS.Item>

          </TabBarIOS.Item>

          <TabBarIOS.Item
            selected={this.state.selectedTab === 'thirdTab'}
            title='Third Tab'
            icon={require ('./Icons/IconImagesThirdTabIcon.png')}
            onPress={() => this._tabPressed('thirdTab')}>
          <NavigatorIOS
            style={styles.container}
            ref="nav"
            initialRoute={{
              title: 'ThirdTab',
              component: ThirdTabComponent,
              navigationBarHidden: false,
              showTabBar: true,
              passProps: {
                //pass props here
              },
            }}/>
          </TabBarIOS.Item>

        </TabBarIOS>
      );
    }


@horatiua
Copy link

horatiua commented Sep 9, 2016

@mcampsall
Thanks for your suggestion. The issue is that right now I've already implemented a Navigator in every TabBarIOS.Item, as it best fits my app's needs. I nested this TabBarIOS in another Navigator in order to make TabBarIOS disappear. It's an ugly solution (as I had to create some kind of router in order to work fine with Redux), but it works...
A "navigationBarHidden" property for TabBarIOS would be very useful, though.

@longminxiang
Copy link

RCTWrapperViewController.m

- (BOOL)hidesBottomBarWhenPushed
{
  return self.navigationController.viewControllers.count != 1;
}

RCTTabBar.m

- (void)reactBridgeDidFinishTransaction
{
  ...
  
  if (_tabsChanged) {
    
    NSMutableArray<UIViewController *> *viewControllers = [NSMutableArray array];
    for (RCTTabBarItem *tab in [self reactSubviews]) {
      UIViewController *controller = tab.reactViewController;
      if (!controller) {
        NSArray *tabSubViews = [[[tab reactSubviews] firstObject] reactSubviews];
        RCTNavigator *navigator = [tabSubViews firstObject];
        if (!tabSubViews.count) {
          tab.onPress(nil);
          return;
        }
        else if ([navigator isKindOfClass:[RCTNavigator class]]) {
          controller = navigator.reactViewController;
        }
        else {
          controller = [[RCTWrapperViewController alloc] initWithContentView:tab];
        }
      }
      [viewControllers addObject:controller];
    }

    _tabController.viewControllers = viewControllers;
    _tabsChanged = NO;
    RCTTabBarItem *tab = (RCTTabBarItem *)[[self reactSubviews] firstObject];
    tab.onPress(nil);
  }

  ...
  
}

@facebook facebook locked as resolved and limited conversation to collaborators Jul 22, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests