今天说的是在 TabBar 嵌套 Nav 时,进行 Push 的时候隐藏 TabBar 的问题。
之前项目也需要这么做,那时候 iOS7 还没出,也是各种搜罗,后来的解决方法是当 push 操作的时候自己隐藏 Tabbar,push 过去视图拉伸适应屏幕,再 pop 回来的时候接再显示 Tabbar,过程复杂还需要自己写动画,最终效果也不是很理想。
前两天公司 APP 上架,当时没有适配 iOS7,在 XCode4.6 上开发编译并发布,居然在 iOS7 下跑起来没有太大的问题,只是一个 Nav 的文字错位,有闪退,不过勉强还能用,其中有自定义 Tabbar,有很多动画,后来在一篇介绍 iOS7 适配的文章中看到这么一句话:
在 Xcode 4.6 上使用 iOS 6 SDK 进行编译的 app 在 iOS 7 上运行时是采用一种特殊的模拟模式,它试图保存 app 原来的样子。但是一旦你升级到了 Xcode 5,在 iOS 7SDK 上编译,你的 app 就会开始出现状况了。
已经写的很清楚了,于是我再到 Xcode5 中编译运行原来的项目,就破漏百出了,开始完全崩溃,各种问题浮现。
好了,回到今天说的正题,先和大家说说 hidesBottomBarWhenPushed,从这个属性名也能知道它的意思了,官方的解释是这样:
If YES, then when this view controller is pushed into a controller hierarchy with a bottom bar (like a tab bar), the bottom bar will slide out. Default is NO.
大致意思是如果为 YES,当这个控制器 push 的时候,底部的 Bar,比如 Tabbar 会滑走,也就是不会在 push 后的视图上显示出来,默认值为 NO。
我讲的场景大概为这个样子:
最外面是一个 TabBarController,套了两个 NavgationController,当其中一个 VC push 下去的时候,一般情况是这样:
当隐藏 Tabbar 的时候再 push,效果是这样:
怎么样,是不是有时候确实会遇到这样的情况?其实苹果真的考虑的很周全,为我们创造了hidesBottomBarWhenPushed这个属性,为了解决这个问题。代码非常简单,一句或者两句话即可,这里得分几种 Push 的情况。
Case1:xib 加载或者 Storyboard 用 identifier 获取 Controller
UIViewController *v2 = [self.storyboard instantiateViewControllerWithIdentifier:@"v2"];
v2.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:v2 animated:YES];
Case2:拉线,也就是 Storyboard 用 performSegue
self.hidesBottomBarWhenPushed = YES;
[self performSegueWithIdentifier:@"tov2" sender:nil];
self.hidesBottomBarWhenPushed = NO;
Tip:经测试证明,此种方式只会对后面的一级生效,继续往后 Push 还会出现 TabBar,要继续往后 push 也隐藏 Tabbar 还得使用 Case3 的方法,也建议如此!
Case3:拉线,在 prepareForSegue 函数里
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
[segue.destinationViewController setHidesBottomBarWhenPushed:YES];
}
更方便的做法:如果你在用 Storyboard,可以在 ViewController 的设置面板中把 Hide Bottom Bar on Push
属性勾选上,效果和上文代码一样。
暂时就用到这几点,我之前的做法,自己手动隐藏,拉伸 view,显示不但麻烦,兼容性也不好,移到 iOS7 上问题多多,不过用这个属性可以非常方便的实现此需求,并且在 iOS6 上也完美兼容哦。
**注意:**还有个问题,这个属性只支持非自定义的 Tabbar,也就是只支持原生 Tabbar,如果是自定义的 Tabbar 会产生你意想不到的效果,我之前就遇到过,因为使用 hidesBottomBarWhenPushed 后,系统内部会处理 TabbarController 上 Tabbar 这个 View,我之前自定义的 Tabbar 做法是吧原生 Tabbar 这个 View 隐藏掉,然后添加到自己绘制的 Tabbar View 上去,缺点就是这样你的自定义的 TabBarview 接收不到系统应有的一些响应,于是我尝试着把自定义的 TabBar View 添加到原来的 TabBar View 上,也就是不隐藏原生的 TabBar,而是覆盖在上面,看不出任何区别,效果也能达到上面图片的效果!