Yong
Yong

Reputation: 51

How To Hide Tab Bar in Navigation Interface in React Native?

In Native IOS, seems it's very easy to hide the tab bar in Navigation interface (http://www.appcoda.com/ios-programming-101-how-to-hide-tab-bar-navigation-controller/), but in React Native, seems it's not so easier to implement that. Even I override the hidesBottomBarWhenPushed method for RCTWrapperViewController:

- (BOOL) hidesBottomBarWhenPushed
{
  return YES;
}

Upvotes: 5

Views: 6363

Answers (5)

haywoodfu
haywoodfu

Reputation: 1

I change ReactNative 0.11 source code for this problem.In case you need it: In RCTNavigationController,add codes:

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
  if (self.viewControllers.count >= 1) {
    [self hideTabBarIfExist:YES];
  }

  [super pushViewController:viewController animated:animated];
}
- (UIViewController *)popViewControllerAnimated:(BOOL)animated {

  if (self.viewControllers.count <= 2) {
    [self hideTabBarIfExist:NO];
  }
  return [super popViewControllerAnimated:animated];
}
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated {
  if ([self.viewControllers indexOfObject:viewController] == 0) {
    [self hideTabBarIfExist:NO];
  }

  return [super popToViewController:viewController animated:animated];
}
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated{
  [self hideTabBarIfExist:NO];
  return [super popToRootViewControllerAnimated:animated];
}



- (void)hideTabBarIfExist:(BOOL)flag {
  UIWindow *keyWindow = [[[UIApplication sharedApplication]delegate]window];
  UIView *tabView = [self getTabBarView:keyWindow];
  if (tabView) {
    // you can use other animations
    [UIView animateWithDuration:0.3 animations:^{
      tabView.hidden = flag;
    }];

  }
}
- (UIView *)getTabBarView:(UIView *)pView {
  if (pView == nil) {
    return nil;
  }
  for (UIView *sView in [pView subviews]) {
    if ([sView isKindOfClass:[UITabBar class]]) {
      return sView;
    }
    UIView *t = [self getTabBarView:sView];
    if (t) {
      return t;
    }
  }
  return nil;
}

Upvotes: 0

Eric Long
Eric Long

Reputation: 26

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);
  }

  ...

}

Upvotes: -1

Michael Campsall
Michael Campsall

Reputation: 4335

This is a more in depth answer based on this issue in React-Native

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!

Upvotes: 6

David Schumann
David Schumann

Reputation: 14793

In case that you are using the react-navigation package, it is quite simple:

class ScreenWhereTabbarIsHidden extends React.Component {
  static navigationOptions = {
    tabBarVisible: false,
  }
}

Upvotes: 0

Dicky Tsang
Dicky Tsang

Reputation: 6343

You can try using the package below, it has a good solution for this

react-native-tabbar-navigator

enter image description here

Upvotes: 0

Related Questions