IOS研究之UITabBarController隐藏tabBar以及addChildViewController



最近我所在的项目组对项目进行了一些基础组件的优化,其中有关于UITabBarController隐藏tabBar的问题感觉有必要总结下。
一,需求分析
先来说说项目基本需求:整个项目由左侧栏和主视图组成,主视图主体是一个UITabBarController,下属几个嵌套了UINavigationController的UIViewController。
要求:当在页面上下滑动的时候,根据用户手势需要隐藏显示底部栏,也就是默认的UITabBarController的tabBar。
我在设计的时候是将左侧栏和主视图通过addChildViewController的方式添加到一个容器UIViewController中,并使用了UITabBarController自带的tabBar。隐藏显示tabBar是通过修改tabBar的frame来实现的。界面布局演示代码如下:对CoreAnimation不够清楚的可以看CALayer和CATransaction的详细教程

其中MyUITabBarController中的演示代码如下:

在测试中发现:在iOS SDK6的环境下移动tabBar后,界面会留出空白,也就是说UITabBarController的tabBar的部分实际上是独占了该区域,即使强制将tabBar通过设置frame将tabBar移开,在该区域也不会显示其他内容。关于这个问题,github上有一个解决方案:点击查看
该方案代码很简洁:就是在移动tabBar之后,修改视图的frame大小,问题看似解决了。

二,我为什么没有使用UITabBarController_setHidden
似乎UITabBarController_setHidden能够解决问题,但在实际使用的时候发现一个问题,当使用pushViewController弹出一个UIViewController【配置hidesBottomBarWhenPushed=YES,页面弹出时tabBar隐藏】,接着popViewControllerAnimated弹回时,tabBar会自动显示并将所属页面的frame重新设置了。这样,设置页面frame的时机不好控制,另外这种方式在页面切换的时候也会有些不太美观的效果。
使用系统自带的tabBar或者navigationBar的好处是显而易见的,不过在本例中的情形(需要手势去隐藏显示底部栏),使用自定的tabBar反而不好处理。
尝试失败之后,我决定使用自定义的tabBar,想要自定义tabBar,一个问题就是怎么隐藏自带的tabBar。

三,如何隐藏UITabBarController自带的tabBar
网络上有方法:
self.tabBar.hidden = YES;
甚至是
[self.tabBar removeFromSuperview];
这些确实能实现隐藏tabBar的功能,但是隐藏了之后在tabBar原有的位置没有填充上内容。正确的做法是:
将UITabBarController中的各个RootViewController进行如下设置:
self.homeViewController.hidesBottomBarWhenPushed = YES;
在我的工程中,还遇到了一个问题:即使设置了hidesBottomBarWhenPushed,在界面的底部还是留有一块没有内容的区域(正好是tabBar的区域)。经过查询,发现原因是在添加主体UITabBarController到容器UIViewController的时候,使用了addChildViewController的方式,将addChildViewController去掉,只保留addSubview的方式,一切运行正常。

四,addChildViewController怎么能影响到UITabBarController的tabBar
这个问题我暂时不清楚是由什么造成的。但说到这里了就谈谈我对addChildViewController这种方式的看法:使用addChildViewController的方式来处理本文描述的场景并没有什么好处。addChildViewController这种方式我感觉主要是为了能方便页面切换(使用transitionFromViewController方法),而本场景中,并不是“两个页面切换”,而是左侧栏和主体视图一直都存在,只是通过手势移开或者显示各自的view而已。
之前我都是只使用addSubview将左侧栏的view和主体view(都是UIController的view)依次添加到一个容器上,网络上有人说“[viewController.view addSubview:someOtherViewController.view];”这种方式其实对是UIViewController的误用,因为这么做“将不会触发被加入view hierarchy的view的controller的viewWillAppear:方法”。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。