13
votes

I am trying to do the following.

I have a tab bar controller with 2 tabs in it. Both the tabs are navigation controller with a table view on each of them.

Now when I select one cell of the table in the first tab, I am pushing another tab bar controller, so I would like to hide the tab bar of the parent tabbarcontroller, and when I click the back button on the navigation bar I would like to see the the parent tab bar again, as I am in my parent tab bar view.

I tried hidesbottombarwhenpushed and it hides the parent tab bar controller tab bar but when I click back it doesn't brings it back.

6

6 Answers

38
votes

Ok, So finally I got my answer, this is what I am suppose to do.

self.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:aViewController animated:YES];
self.hidesBottomBarWhenPushed=NO;

So basically hidesBottomBarWhenPushed = YES, and then push your view controller and then hidesBottomBarWhenPushed = NO; this works like a charm.

Thanks to eddy and his post here

5
votes

The accepted answer had a problem to me.

My app had a navigation with the depth of three UIViewController.

  • The FirsViewController show's the UITabBar. (Correct)
  • The FirsViewController pushes the SecondViewController, and the SecondViewController don't show's the UITabBar. (Correct)
  • The SecondViewController pushed the ThirdViewController, and the ThirdViewController show's the UITabBar. (Incorrect)
  • The ThirdViewController popped to the SecondViewController, and the SecondViewController show's the UITabBar. (Incorrect)
  • The SecondViewController popped to the FirstViewController, and the FirstViewController show's the UITabBar. (Correct)

The solution for me was setting the delegate of UINavigationControllerDelegate

swift:

self.navigationController?.delegate = self

Objective-c:

self.navigationController.delegate = self;

And then implement the following delegate method

Swift:

fun navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {

    if fromVC.isKindOfClass(FirstViewController) && toVC.isKindOfClass(SecondViewController) {

        self.hidesBottomBarWhenPushed = true;

    }
    else if fromVC.isKindOfClass(SecondViewController) && toVC.isKindOfClass(FirstViewController) {

        self.hidesBottomBarWhenPushed = false;

    }

    return nil

}

Objective-c:

-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                 animationControllerForOperation:(UINavigationControllerOperation)operation
                                              fromViewController:(UIViewController*)fromVC
                                                toViewController:(UIViewController*)toVC
{

    if ([fromVC isKindOfClass:[FirstViewController class]] && [fromVC isKindOfClass:[SecondViewController class]]) {

        self.hidesBottomBarWhenPushed = true;

    }
    else if ([fromVC isKindOfClass:[SecondViewController class]] && [fromVC isKindOfClass:[FirstViewController class]]) {

        self.hidesBottomBarWhenPushed = false;

    }

    return nil;

}

Hope it helped.

1
votes

As the Apple documentation states, you can't push a UITabBarController instance on a NavigationController. And there's a good reason for that: how do you get back from the pushed tab bar controller if you selected another item in the tab bar?

The simple answer is: don't do that, it will confuse your user. You can try swapping the first view controller for another view controller that may be a tab bar controller, but do not use the push paradigm for that: use an explicit button instead that will swap your first tab bar controller for the second one, preferably using a visual transition.

You can look at the setAnimationTransition:forView:cache: documentation for the UIView class to know how to swap, say, a tab bar controller for another:

  1. Begin an animation block.
  2. Set the transition on the container view.
  3. Remove the subview from the container view.
  4. Add the new subview to the container view.
  5. Commit the animation block.

In this case, the container view will be the application's window.

1
votes

You can also hide it using the attributes inspector when select the tabBar controller

enter image description here

0
votes

Set hidesBottomBarWhenPushed = true in the controller that will be pushed.

For hide all controllers put into prepare for segue

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    segue.destination.hidesBottomBarWhenPushed = true
}
0
votes

In your FirstViewController use

self.hidesBottomBarWhenPushed = true

in your SecondViewController use

override func willMoveToParentViewController(parent: UIViewController?) {
  if parent == nil {
    var viewControllers = self.navigationController!.viewControllers
    if ((viewControllers[viewControllers.count - 2]).isKindOfClass(FirstViewController.self)) {
      (viewControllers[viewControllers.count - 2] as! FirstViewController).hidesBottomBarWhenPushed = false
    }
  }
}