tabbar隐藏(tabbar变黑和切换tab时突然被隐藏)

关于tabbar隐藏,有两种方法:
(个人最优隐藏方案在最后)

1、self.tabBarController.tabBar.hidden = YES;

这是tabbar自带的方法。在需要的页面直接使用self.tabBarController.tabBar.hidden = NO;和self.tabBarController.tabBar.hidden = YES;来控制显示和隐藏。

这种方式可能会造成推出的页面底下tabbar位置变黑或者点击事件无响应。这种你打开图层去看,就能看到,\color{red}{原因}是view的frame没有全屏:

层级图

\color{red}{解决:}在需要的页面修改frame即可。

-(void)viewWillLayoutSubviews{
    //这里改成你需要的frame。
    self.view.frame = CGRectMake(0, SafeAreaTopHeight, ScreenWidth, ScreenHeight - SafeAreaTopHeight);
    [super viewWillLayoutSubviews];
}

2、vc.hidesBottomBarWhenPushed = YES;

(此处的vc是你要push的那个子页面vc,不是当前vc!,如果要使用当前vc,则在当前push代码后面要加self.hidesBottomBarWhenPushed = NO;那更烦人了,我不会这么用。而且看完后面原因解释也能理解为什么是子页面vc。)
  这是viewcontroller的方法。如果你是在重写UINavigationController的push方法中直接设置的,会出现两个问题:1、push进去tabbar会隐藏,但是返回之后tabbar不会显示;2、运行好后直接点击切换tab,tabbar也会隐藏。
(单独在某个页面的点击按钮事件里写这个是没有问题,但项目里一般都会写在重写UINavigationController的push方法中进行全局设置,以减少代码量。造成问题原因写在后面。)
  于是,在tab的几个主页面上用self.tabBarController.tabBar.hidden = NO;来控制回到根控制器时tabbar的显示,以此来解决问题1。然后在tabbar的didSelectViewController代理里再进行一次显示, 以此来解决问题2。
  第一次push进去和返回都没问题,点击来回切换也没有问题,然而当你第一次push完成返回到根控制器之后进行另一个页面push的时候,tab并没有被隐藏。
  于是,在vc.hidesBottomBarWhenPushed = YES;的地方再加上一句self.tabBarController.tabBar.hidden = YES;(层层面向问题逐个解决,至此可以解决问题,但有点麻烦!了解原因之后,可以面向根本解决问题。)

//1、在tab的几个主页面的viewwillappear里面写不隐藏tabbar
self.tabBarController.tabBar.hidden = NO;

//2、一般这两句会写在自定义UINavigationController或者重写的UINavigationController中的push方法里,做整体设置,这样不用到处写。
self.tabBarController.tabBar.hidden = YES;
viewController.hidesBottomBarWhenPushed = YES;

//3、解决来回切换tab时,tabbar突然隐藏
#pragma mark --- tabbarDelegate
-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{
    if (self.tab.tabBar.isHidden) {
        self.tab.tabBar.hidden = NO;
    }
}

\color{red}{原因:}

hidesBottomBarWhenPushed官方文档解释
  百度翻译一下:添加为导航控制器子级的视图控制器可以在屏幕底部显示可选工具栏。最顶层视图控制器上此属性的值确定工具栏是否可见。如果此属性的值为true,则工具栏将隐藏。如果此属性的值为false,则该条可见。
  不理解?看下xcode中的解释,是不是就清晰明了了:
xcode解释
  个人总结一下:官方解释中的关键点就是”添加为导航控制器子级“和”最顶层视图控制器“。本质就是压栈,当vc压入栈时,设置了隐藏tabbar,那么包含此vc的之后所有vc的tabbar都将被隐藏。(这点可解释为什么vc.hidesBottomBarWhenPushed的vc是你要push的那个子页面vc。)
  知道原因之后,上面那种面向过程的解决方法就不是最优的解决方法了(至少从代码量上看,并不精简),可以把所有有关tabbar隐藏的代码都删掉,只需要在重写UINavigationController的push方法中如下设置即可:(\color{red}{我认为的最优隐藏方案:}

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{

    if (self.childViewControllers.count > 0) {
        viewController.hidesBottomBarWhenPushed = YES;
    }
    
    [super pushViewController:viewController animated:animated];
}

关于代码中 0 的解释:这是表示当push了第几个页面之后,tabbar会跟随push动作一起隐藏,>0表示从第一个push出的那个页面就会隐藏tabbar,进一步解释:如果是>3,则表示,当push出的页面是第4个被push出的页面的时候,tabbar隐藏,前3个push出的页面不会隐藏tabbar。

  此时来解释为什么一开始在重写push方法中不加childVC.count的判断而直接使用viewController.hidesBottomBarWhenPushed = YES;会导致返回之后的tab也消失:当你运行项目的时候,nav因为是加在根控制器上,所以项目加载根控制器时是采用push的方式,将根控制器推出,此时你在push方法中打断点会发现,它走过了这个方法,而当前走进这个方法的vc是你tab主页的那几个vc(但它们不是childVC,人家是根视图,这点要搞清楚,这跟count设置值有关),此时它也就直接进行了hidesBottomBarWhenPushed = YES的赋值,也就是说当你启动项目的时候,tab主页的hidesBottomBarWhenPushed也被设置成了YES,于是你首页push返回和点击切换tab的时候,tab主页的tabbar都会隐藏。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容