需求:
香蕉球APP的tabBar本来一共有5个,由于战略原因,tabBar中的“活动中心” 需要动态由后台配置决定是否显示。
理想情况下的做法:
1,获取当前tabBarVC中的所有子VC,得到一个数组 mutArr。
2,根据后台返回的bool值activityCenterOpen,ture为显示,false为隐藏。
3,(1),若为false,判断mutArr是否包含“活动中心”的VC,包含 则将“活动中心VC”从mutArr中删除。
(2),若为true,判断mutArr是否包含“活动中心”的VC,不包含 则将“活动中心VC”插入到这个mutArr数组,index为2。
4,调用self.tabBarController.viewControllers = mutArr;
则完成动态配置要求。
遇到问题:
执行前面3,(1)的时候是没有问题的,能成功将“活动中心”从tabBar中删除,
然而在3,(2)的时候要将”活动中心“插入到tabBar的第三个的时候,实际显示确实这样的:
没错!活动中心被加在了最后一个item上了。
通过调试 发现mutArr中的各个VC的顺序,并没有改变,“活动中心VC”在数组中位置就是index=2,没有问题。
猜测:
面对这样的结果,只能猜测tabBarVC在重置viewControllers的时候是不管mutArr中的顺序的,而是先判断即将设置的VC是否在当前的VCs 里面,若有之前已经存在过,则不再添加,若是不存在就将新的VC设置在最右边显示。也就是说 self.tabBarController.viewControllers = mutArr; 并不是真正的重置!
尝试:
通过这样的猜测,已经可以想象到解决方案了,那就是在插入VC的时候,先把之前的都去掉,再重新复制,即,
1 | self.tabBarController.viewControllers = @[]; |
结果只是第一行代码起了作用,也就是tabBarItem全部移除了。
没有道理。莫非是先把VCs设置为空数组之后,就不能更改了? 后来将代码改成
1 | [mutVCs insertObject:nav atIndex:2]; |
结果依然是第一行代码起作用,第二行没有设置上,显示为
并没有放弃,把arr1改成2个试一下。
1 | [mutVCs insertObject:nav atIndex:2]; |
神奇的事情发生了,完美的显示出来想要的效果
解决:
得出的结论是,
1,tabBarVC在重置viewControllers的时候是不管mutArr中的顺序的,而是先判断即将设置的VC是否在当前的VCs 里面,若有之前已经存在过,则不再添加和改变顺序,若是不存在就将新的VC设置在最右边显示
2,若是tabBarController之前的viewControllers为小于等于1个,那么再次对viewControllers赋值,是起不到作用的。
Wtf!,虽然1的结论可以证实,但是2的结论这么草率??!怎么会有这么奇怪的用法??
再验证:
只能再次去验证其正确性。调试了很多次发现结果变幻莫测,难以找到其规律,比如把index<=1时,即:
1 | [mutVCs insertObject:nav atIndex:1]; |
结果竟然
为什么会跟insert的index也有关系!,这么乱的复杂情况下面到底藏着怎样的秘密?
再猜测:
经过调试发现发现一个现象:
每当我对self.tabBarController.viewControllers = arr1;进行设置时,若arr1中包含自己(也就是Self),那么第二行self.tabBarController.viewControllers = mutVCs; 就会有效!。
通过debug 发现,若arr1中包含self,此时打印self.tabBarController,会打印出self.tabBarController的指针,而arr1中没有包含self时,打印出的是self.tabBarController=nil。
这么说来 第二行代码无效就解释的通了!!
最后结论:
每当调用tabBarController的setVCs的时候 ,会立即生效并生成相应的tabBarItems, 若这些VCs里面有当前self的VC,那么根据self.tabBarController就能找到self的tabBarController,而如果setVCs里面的VC没有self,那么再继续调用self寻找self的tabBarController自然就找不到了,因为tabBarController跟self已经没有半毛钱关系了。
欢迎访问我的微博留言:肚子吃撑的杜