hideBottomBarWhenPushed 使用

2,735 阅读3分钟

一、tabBar隐藏显示

在vcA中显示tabBar,在vcB中隐藏tabBar。类似这种例子的需求不少。自我总结一下哈哈哈。

谷歌下后找到了如下几种方法:

  • 1._tabBarController.tabBar.hidden = YES;
  • 2.重写hidesBottomBarWhenPushed
  • 3.self.hidesBottomBarWhenPushed = YES;

1._tabBar.hidden = YES;

首先想从这个简单的属性设置讲起,因为实际情况中我也会直接这么做,但是这么做带来的后果是如下:

在需要隐藏的页面来上那么一句 _tabBarController.tabBar.hidden = YES;

tabBar的确隐藏了,但是tabBar的位置会出现一部分空缺,如下图

tabBar空缺
为什么会出现上面的情况,从

立体结构图

view层级图
从上面的这幅图可以看出,tabBar的确隐藏了,但是我们看到的空缺部分是建立在UINavigationController抑或是UITabBarController的某一类view上的一部分。(推测)而这个view又对controller.view进行了约束,导致了无论我们如何进行

[self.view addSubview:subView];

抑或是改变_view的大小,这部分的空缺仍然无法填补。

不隐藏之前的样子

不隐藏时候的样子
如何去填补这部分黑影? 我尝试了一下重新布置_view的frame让其覆盖,但是总是不能完成覆盖。 因此,我个人能力有限,无法解决这样的问题。况且在实际应用场合当中,我也不会通过这一方式来使其隐藏,毕竟界面的部分空缺对用户体验有一定减分。

没有提供实际有效的方法,反而带来了个坑。因此这部分内容也只能作为‘让读者少走弯路’的内容看看哈哈哈哈。

2.重写hidesBottomBarWhenPushed 方法

对于这个方法,苹果的官方文档是:

A view controller added as a child of a navigation controller can display an optional toolbar at the bottom of the screen. The value of this property on the topmost view controller determines whether the toolbar is visible. If the value of this property is true, the toolbar is hidden. If the value of this property is false, the bar is visible.

tabBar的隐藏取决于navigation的栈顶控制器。 我看到网上有如下写法

@implementation SecondViewController
// 在要push进栈的控制器中重写该方法
- (BOOL)hidesBottomBarWhenPushed {
    return (self.navigationController.topViewController==self);
}
@end

这个方法会在 -(void)pushViewController:animated:;之后调用。因此,这时候secondVc进栈,等式成立,secondVc中的导航栏被隐藏。但是如果继续将thirdVc push进栈(不对thirdVc的hidesBottomBarWhenPushed进行重写),会发现,thirdVc的tabBar从新出现。 原因是: 在secondVc中执行了[pushviewController:animated]'之后,secondVc的hidesBottomBarWhenPushed依旧会被触发(可以打断点试试)。而此时thirdVc进入栈成为栈顶控制器,等式不成立,故而tabBar复现。

如何隐藏thridVc的tabBar呢?可以像secondVc一样,对该方法再次重写。 而在以后的开发中,针对与任何一个需要隐藏起tabBar的viewController,必要时候还是需要重写该方法,避免给自己挖坑。

一直重写觉得有点麻烦,也可以集中写在自己的navViewController中的 -(BOOL)hidesBottomBarWhenPushed;

3.self.hidesBottomBarWhenPushed = YES;

这类方法和上述的第二种方法修改的对象也是一致的。 但是修改的时候需要注意如下几个问题

  • 1.问题一:secondVC.hidesBottomBarWhenPushed = YES;

此时secondVc在push的时候就会隐藏tabBar,同时pop出来时候,tabBar依旧显现。然而在thirdVC push进栈时候,如果想要thirdVc的tabBar显示,此时通过thirdVc.hidesBottomBarWhenPushed = NO无法让thirdVc的tabBar显现出来的。至于为什么,官方文档好像也没有解释清楚:

If the value of this property is true, the toolbar is hidden. If the value of this property is false, the bar is visible.

倒是在stackoverflow找到了网友解答(如下):

网友解答

  • 2.问题二:self.hidesBottomBarWhenPushed = YES;

如果在push secondVc进栈时候,写入 self.hidesBottomBarWhenPushed = YES; 会导致pop回firstVc 时候,tabBar不能出现.

解决方法:

实际情况中,如果真有必要使得thirdVc的tabBar显示出来,可以采用下面的写法

// 在push secondVc 的时候
SecondVc *secondVc = [SecondVc new];
secondVc.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:secondVc animated:YES];
secondVc.hidesBottomBarWhenPushed = NO ; 

采用这种肉夹馍的写法,在push thirdVc进栈之后其tabBar依旧坚挺!😂

补充一些tabBar的小技巧: 设置tabBarItem的imageInset属性可以对tabBar内部的宽距进行设置。


参考

苹果文档-hidesBottomBarWhenPushed

stackoverflow-1

stackoverflow-2