iOS 多window statusbar rotation 控制

一、问题的产生

临近发版时,同事突然找我帮忙看一个statusbar旋转的问题:应用主页只支持竖屏(有子页面需要横屏,所以app还是需要支持portrait、landscapeLeft、landscapeRight三个方向),打卡手机的横竖屏锁,旋转手机,只支持 portrait 的首页的statusbar方向竟然发生了旋转。

二、问题的定位

发现这个问题,菊花一紧,赶紧下了一个appstore线上包,发现是好的,万幸万幸!线上是好的,问题一定是最近的修改导致的,下面记录一下问题定位的过程:
1,查看了一下工程plist,一切正常。
2,把当前的podfile和线上包所用的podfile进行比较,发现除了各个子模块升级外,仅仅引入了一个新的子模块,从名字看,是与一些数据统计相关的库。
3,经过2的分析,我猜测大概率是某个兄弟姐妹在升级模块的时候,搞了与旋转相关的事情,在钉钉群里@所有人,问是否有人改过,得到的回到是NO,这就奇怪了。
4,当所有人都说没改过这块的时候,我是持怀疑态度的,心想一定要找出是谁改的,于是down下来所有模块的代码,添加了 [UIViewController shouldAutoRotate] 的符号断点,并在时间里面加上了堆栈输出,可惜没有得到有用的信息,在符号断点执行时,执行 po self, 结果告诉我 self 没有定义,想通过符号断点来确定调用位置的办法落空了。
5,此时,一个上午已经过去了,很迷茫,下午吃完饭,搜了一下各种statusbar旋转的case,和我遇到的现象差异很大,心里开始着急了,用英文在stackoverflow上搜索,说多window时,可能会影响到旋转,这我觉得有可能,赶紧在代码上打了个断点,并执行:po [UIApplication sharedApplication].windows,不执行不知道,一执行吓了一跳,竟然有3个window,其中一个竟然是数据统计相关库的window,心想,大概就是这个window的锅了,在podfile中注释掉这个库、注释掉调用这个库的方法,重新运行,发现一切正常,OK,由此,定位到问题了,but why?

三、问题的分析

在(二)中,我找到了出问题的地方,但是对于为什么会出现这种情况,却不知道,要搞清楚这个问题,需要搞一个多window的demo来进行验证,在github上搜索 multiple UIWindow,找到一个demo,https://github.com/y310/MultiWindowSample 在这个demo上稍作修改,并给 MWSViewController、MWSSubWindowViewController都添加了方法:

- (BOOL)shouldAutorotate{
    return NO;
}

对window进行选择,视图也随着旋转,statusbar位置正常。

接下来我要让多window生效了,在MWSSubWindowViewController 中,将shouldAutorotate的返回值改为YES,点击 showWindow按钮,旋转手机,发现MWSSubWindowViewController和statusbar都旋转了。

然后,我再做一下修改,将MWSViewController中的 shouldAutorotate 设置为YES,而 MWSSubWindowViewController 中的 shouldAutorotate 设置为NO,点击 showWindow按钮,旋转手机,发现MWSSubWindowViewController没有旋转,而statusbar和MWSViewController旋转了,页面混乱。到此时,我们就可以明白,如果MWSSubWindowViewController 不是半透明的话,statusbar 相对于 MWSSubWindowViewController 就对不上了。

此时的现象,已经可以解释我们出现的statusbar异常的问题了。但是还是略有差异,因为我们的可见window只有一个,需要再做修改:在 MWSViewController 中,将 shouldAutorotate 改为返回NO;修改 openWindow:(id)sender 方法,注释掉 [self.window makeKeyAndVisible]; 即,我们不让subwindow显示出来。将MWSSubWindowViewController中,将shouldAutorotate 改为返回YES,运行工程:

- (IBAction)openWindow:(id)sender {
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    MWSSubWindowViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"SubWindow"];
    controller.window = self.window;
    self.window.rootViewController = controller;
//    [self.window makeKeyAndVisible];
}

点击 MWSViewController 上的show window 按钮,还是停留在MWSViewController之上,这时再旋转手机,statusbar 与内容对不上了,问题复现。

四、问题的知识点总结

1,VC自己是否旋转,由VC自己的 shouldAutorotate 方法决定。
2,statusbar 是否旋转,由所有的多 window 的 rootViewController 的 shouldAutorotate 共同决定。

你可能感兴趣的:(ios开发)