tabBar中动态插入tabBarItem的trick,并由此引发的进一步深入

Posted by 杜文杰 on 2018-05-25

需求:

香蕉球APP的tabBar本来一共有5个,由于战略原因,tabBar中的“活动中心” 需要动态由后台配置决定是否显示。

1

理想情况下的做法:

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的第三个的时候,实际显示确实这样的:
2

没错!活动中心被加在了最后一个item上了。
通过调试 发现mutArr中的各个VC的顺序,并没有改变,“活动中心VC”在数组中位置就是index=2,没有问题。

猜测:

面对这样的结果,只能猜测tabBarVC在重置viewControllers的时候是不管mutArr中的顺序的,而是先判断即将设置的VC是否在当前的VCs 里面,若有之前已经存在过,则不再添加,若是不存在就将新的VC设置在最右边显示。也就是说 self.tabBarController.viewControllers = mutArr; 并不是真正的重置!

尝试:

通过这样的猜测,已经可以想象到解决方案了,那就是在插入VC的时候,先把之前的都去掉,再重新复制,即,

1
2
self.tabBarController.viewControllers = @[];
self.tabBarController.viewControllers = mutArr;

结果只是第一行代码起了作用,也就是tabBarItem全部移除了。

没有道理。莫非是先把VCs设置为空数组之后,就不能更改了? 后来将代码改成

1
2
3
4
[mutVCs insertObject:nav atIndex:2];
NSArray *arr1 = [mutVCs subarrayWithRange:NSMakeRange(0, 1)];
self.tabBarController.viewControllers = arr1;
self.tabBarController.viewControllers = mutVCs;

结果依然是第一行代码起作用,第二行没有设置上,显示为

3

并没有放弃,把arr1改成2个试一下。

1
2
3
4
[mutVCs insertObject:nav atIndex:2];
NSArray *arr1 = [mutVCs subarrayWithRange:NSMakeRange(0, 2)];
self.tabBarController.viewControllers = arr1;
self.tabBarController.viewControllers = mutVCs;

神奇的事情发生了,完美的显示出来想要的效果

4

解决:

得出的结论是,
1,tabBarVC在重置viewControllers的时候是不管mutArr中的顺序的,而是先判断即将设置的VC是否在当前的VCs 里面,若有之前已经存在过,则不再添加和改变顺序,若是不存在就将新的VC设置在最右边显示

2,若是tabBarController之前的viewControllers为小于等于1个,那么再次对viewControllers赋值,是起不到作用的。

Wtf!,虽然1的结论可以证实,但是2的结论这么草率??!怎么会有这么奇怪的用法??

再验证:

只能再次去验证其正确性。调试了很多次发现结果变幻莫测,难以找到其规律,比如把index<=1时,即:

1
2
3
4
[mutVCs insertObject:nav atIndex:1];
NSArray *arr1 = [mutVCs subarrayWithRange:NSMakeRange(0, 2)];
self.tabBarController.viewControllers = arr1;
self.tabBarController.viewControllers = mutVCs;

结果竟然

5

为什么会跟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已经没有半毛钱关系了。


欢迎访问我的微博留言:肚子吃撑的杜