iOS14 missing TabBar on popping multiple ViewControllers

Seems like there is a confirmed bug on Xcode12 + iOS14.

I have a UINavigationController on each item of a UITabBar, and I've set hidesBottomBarWhenPushed to YES on every secondary ViewControllers, so the TabBar will only be shown on the rootViewController of navigationController. But when I try popping multiple ViewControllers, like pop C from stacks like A-B-C, I found that the TabBar just missing on A.

Also another weird part, when I print navigationController.viewControllers in viewWillDisappear: method on C, I found it printing like "C-A". How C moved to the top of the array??

This is confirmed on a simple demo app, wonder when it will be fixed.

Accepted Reply

Same problem to me

You can re-write UINavigationController push function

Code Block
// fix: sometimes push and then popback no tabbar error
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
  if (self.viewControllers.count == 1) {
    viewController.hidesBottomBarWhenPushed = YES;
  } else {
    viewController.hidesBottomBarWhenPushed = NO;
  }
  [super pushViewController:viewController animated:animated];
}

Replies

We also met the bug when the app builds with Xcode12 on iOS14.
Hope Apple can fix the serious bug.
We have the same problem.
Same problem to me

You can re-write UINavigationController push function

Code Block
// fix: sometimes push and then popback no tabbar error
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
  if (self.viewControllers.count == 1) {
    viewController.hidesBottomBarWhenPushed = YES;
  } else {
    viewController.hidesBottomBarWhenPushed = NO;
  }
  [super pushViewController:viewController animated:animated];
}

Code Block
- (NSArray<kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated {
   if (self.viewControllers.count > 1) {
    self.topViewController.hidesBottomBarWhenPushed = NO;
  }
   
  NSArray<kindof UIViewController *> *viewControllers = [super popToRootViewControllerAnimated:animated];
// self.viewControllers has two items here on iOS14
  return viewControllers;
}


Some vc is still required to set hidesBottomBarWhenPushed = NO, I think popToRootViewControllerAnimated is another solution.

We had the same issue on iOS 14.0 and now have on iOS 14.0.1.
We have the same problem.
Under iOS 13: the debugger breaks at:
  • [UITabBarController tabBar]

[(UITabBar *)[(UITabBarController *)$arg1 tabBar] isHidden] == NO
for popToRootViewControllerAnimated

but not under iOS 14

After debug a demo project, I found that the TabBar still is shown when calling [UINavigationController popToRootViewControllerAnimated:] with NO. With YES, the TabBar will not show.


Demo project
  • This solution worked for me, wish i know the reason

Add a Comment
We have the same problem.my code working in iOS 12 ,13 but not working in iOS 14 . TabBar hidden in automatically.
Also experiencing this issue. What @vitonzhangtt mentioned seems to work but is not ideal.
I tought it's a bug in my code. Hope apple will fix this soon
i've submitted this under feedback assistant, with the link to this thread, lets hope it gets fixed.
Still experiencing this issue.
This is very annoying, we can't compile with XCode 12 because of this problem. It's not viable for us to subclass UINavigationController and change the push function.
Is anybody working at Apple??
Based on the solution from @loo_l

Instead of subclassing UINavigationController or extending it with a new push function, you can achieve the same thing like this.

If you are already setting hidesBottomBarWhenPushed = true manually, you can change it to
hidesBottomBarWhenPushed = navigationController.canHideBottomForNextPush

Code Block
// hidesBottomBarWhenPushed workaround.
public extension UINavigationController {
    // True if `hidesBottomBarWhenPushed` can be set to true, otherwise false.
    // Workaround for iOS 14 bug.
    var canHideBottomForNextPush: Bool {
        // There is a bug in iOS 14 that hides the bottom bar
        // when popping multiple navigation controllers from the stack,
        // and one of them has hidesBottomBarWhenPushed set to true.
        // https://developer.apple.com/forums/thread/660750
        guard #available(iOS 14, *) else {
            return true
        }
        return viewControllers.count == 1
    }
}

Hey we had the same problem with Xcode 12 and iOS 14. We was making archives for upload with old version of Xcode (11.7) until today because that wasn't option anymore.

So we find that solution for when using popToRootViewController:
Code Block
override func popToRootViewController(animated: Bool) -> [UIViewController]? {
    guard #available(iOS 14, *) else {
      return super.popToRootViewController(animated: animated)
    }
     
    viewControllers.forEach({$0.hidesBottomBarWhenPushed = false})
    return super.popToRootViewController(animated: animated)
}

Seems to work for now as a workaround in our case. All animations are still usable. Hope Apple will fix it soon.