hidesBottomBarWhenPushed的使用方法

现在的项目基本都是基于TabbarController + ViewControllers 来进行底层搭建的,如何更好的控制Tabbar的隐藏和显示就是一个需要面临的问题。

常做的做法有两种

  1. ViewWillAppear或者ViewWillDisappear中来控制。
  2. 设置viewControllerhidesBottomBarWhenPushed为YES。
  3. 重写BaseNavigationController的pushViewController方法。

ViewWillAppear或者ViewWillDisappear中来控制

这种做法通常是在BaseViewController中,手动来控制tabbar的隐藏和显示。根据当前控制器的viewControllers来判断是隐藏还是显示。

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    if (self.navigationController.viewControllers.count > 1) {
        self.tabBarController.tabBar.hidden = YES;
    } else {
        self.tabBarController.tabBar.hidden = NO;
    }
}

这种做法可以暂时的解决问题,但是碰到UIToolBar和UITabbar同时使用时就会有问题。当Tabbar隐藏时,Toolbar的位置不会紧挨着底部。所以这时就需要采用做法2。


Tabbar显示时没有问题
Tabbar隐藏时底部会有空隙

设置viewControllerhidesBottomBarWhenPushed为YES。

这里通常存在一个疑问,到底是将谁的hidesBottomBarWhenPushed设置为YES。以ViewControllerA push ViewControllerB为例。

// 在ViewControllerA中调用此方法。
// 注意:这是一个错误的示范。
- (void)testPush {
    ViewControllerB *vc = [[ViewControllerB alloc] init];
    self.hidesBottomBarWhenPushed = YES;
    [self.navigationController pushViewController:vc animated:YES];
}

当采用testPush这种方式进行push时,你会发现进入B页面时,可以正常的隐藏了Tabbar,但是当你从B页面pop回A页面时,你会发现Tabbar没有被正常的显示出来。 这是因为你当你调用self.hidesBottomBarWhenPushed = YES;时,self是ViewControllerA,所以当你退回时也无法显示Tabbar。

正确的写法如下:

// 将B页面的hidesBottomBarWhenPushed设置成YES,才是正确的做法。
- (void)testPush2 {
    ViewControllerB *vc = [[ViewControllerB alloc] init];
    vc.hidesBottomBarWhenPushed = YES;
    [self.navigationController pushViewController:vc animated:YES];
}

重写BaseNavigationController的pushViewController方法

身为一个程序员,你肯定不想每一处的push都写加一行这样的代码,又不能在BaseViewController里将hidesBottomBarWhenPushed的初始值设置成YES(因为Tabbar的rootViewControllers里的ViewController不可以设置这个值)。

比起Swizzling的方式来处理这个问题,重建一个BaseNavigationController并且重写- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated方法会更简单。

我最初的写法如下:

// 注意:这是个错误的写法
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    viewController.hidesBottomBarWhenPushed = YES;
    [super pushViewController:viewController animated:animated];
}

一切看起来都没问题,当push页面时,才会将被push的页面的hidesBottomBarWhenPushed设置为YES。但是实际效果却是Tabbar.rootViewControllers里的viewController的hidesBottomBarWhenPushed也被设置成YES。

原因:
虽然我在代码中没有主动push过这些rootViewController,但是当调用[[BaseNavigationController alloc] initWithRootViewController:vc];时,系统会自动调用BaseNavigationController的pushViewController方法。

所以我们需要将上面的方法修改成:

// 注意:这是个正确的写法
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    if (self.viewControllers.count > 0) {
        viewController.hidesBottomBarWhenPushed = YES;
    }
    [super pushViewController:viewController animated:animated];
}

你可能感兴趣的:(hidesBottomBarWhenPushed的使用方法)