浅谈iOS的多Window处理

本文探讨了iOS中多UIWindow的使用场景,包括全局自定义视图和覆盖UIStatusBar的需求。在处理横屏及旋转时,介绍了强制横屏与跟随设备旋转的区别,并分析了iOS8之前的坐标系问题。文章还详细讨论了直接添加Subview到UIWindow、通过rootViewController添加子视图以及presentViewController时的坑点,并提供了解决方案。
摘要由CSDN通过智能技术生成

概述

想必做iOS的人都知道,我们的App是通过UIWindow这个载体呈现出来的。默认情况下,iOS App对于开发者来说只有一个UIWindow,也就是AppDelegate在applicationDidFinishLaunching里面创建出来的。

但是即使我们什么都不做,在我们的APP里面也会有其他的UIWindow:

  1. 键盘对应的UITextEffectWindow
  2. 状态栏对应的UIStatusBarWindow(准确来说这个Window并不隶属于我们的App)

只不过上述两种UIWindow我们一般不太容易去操作罢了,因此很多问题都无形被掩盖住了。最近正好需要做双十一晚会一个和横屏界面相关的需求,在整个过程中,发现了不少问题,所以接下来我们就说说如果在多个UIWindow状态下存在的一些问题吧。

那么在什么情况下会导致我们想要创建多UIWindow的状态呢?我总结了一下,包括但不限于:

  1. 全局性的自定义HUD,Alert效果(SCAlert)等等。
  2. 需要展示的界面需要盖住UIStatusBar。

其中,第一种需求其实不一定需要创建一个新的UIWindow实例,我们也可以将这些自定义的全局性界面添加到AppDelegate的window上。但是这样就会产生一个问题,由于在iOS8之前,UIWindow的bounds是不会随着旋转而改变的,拿到的永远是处于Portrait模式下的坐标系坐标。因此,对于直接添加在UIWindow上的视图,我们需要自己根据 UIApplicationDidChangeStatusBarOrientationNotification来进行转换处理。

苹果这篇Q&A讲述了比较具体的原因:UIWindow并不会处理rotation事件,而是UIWindow的rootViewController去处理。

而对于第二种问题,添加一个盖在UIStatusBar上的界面,就必须依赖我们自己创建一个新的UIWindow,究其原因在于UIStatusBar本身并不属于我们App内可控的一个控件,而是一个系统级创建出来的产物。
因此,我们必须创建一个WindowLevel大于UIWindowStatusBar的新Window盖在上面才行。

有人会问:咦,奇怪了,为什么你在自己App内添加一个WindowLevel大于statusbar的就可以了呢?你只是在你自身应用内添加了一个UIView(UIWindow的子类),竟然能影响系统级的控件?

不知道大家有没有了解过CALayer这层有个属性叫zPosition。通过操纵这个属性,我们可以调整视图渲染的前后关系。即使有的UIView在构建层级树的时候被后加的UIView所遮盖,但是在构建

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值