一、基本特性
1、UIWindow是一种UIView,但是它是所有用户界面的最顶层背景View,不同于普通的View,它具有事件(Event)的分发能力,是响应链的开始的起点。所以,当我们的应用启动时,我们须要手动提供一个main window给我们的应用。当然,如果你的项目是基于Storyboards的,Storyboards在创建时默认会提供window;
2、window的显示需要通过提供rootViewController来进行用户界面展示,不同的window持有不同的rootViewController;
3、一般情况下,不推荐去创建UIWindow的子类,如果你有这些需求(悬浮框),可以尝试对较高level的View或者直接对window进行操作;
4、绝大部情况下,一个window可以满足正常的界面交互展示需求,当然,苹果也允许我们创建额外的windows,创建额外的windows可以:
(1)displaying content on a connected screen;即用来支持分屏展示;
(2)we can also use a extra window for a handdful of other tasks;用来处理其他的任务
主要对(2)进行几点说明:
当需要进行额外window时,我们需要注意几点的是:
(1)因为要管理多个window,需要合理设置每个window的level;
(2)及时更改你的rootViewController;
(3)因为有且只有一个window可以被显示,需要指定keyWindow;
(4)针对系统keyboard、UIAlertView(已废弃)等事件,需要保证window可以处理对应的事件;
(5)如果需要,注意自定义window坐标系的转换;
5、window有三个浮点型的的level,分别是UIWindowLevelNormal(0)、UIWindowLevelStatusBar(1000)、UIWindowLevelAlert(2000);我们可以通过控制自定义window的level,来控制它们的展示层级;
二、常见的应用场景
1、[UIApplication sharedApplication].keyWindow
前面已经说过,同一时间,只有一个window可以成为keyWindow,这些可以通过makeKeyAndVisible操作来实现;
正常情况下,我们的keyWindow就是我们在启动中设置的UIWindow,但是如果中间进行了window切换,那么[UIApplication sharedApplication].keyWindow也会跟着改变,以下是会影响[UIApplication sharedApplication].keyWindow的几种场景,采用三种的测试代码进行验证:
(1) makeKeyAndVisible方法的调用;如果某个自定义的window调用了这个方法,keywindow会改变,同时也会触发UIWindowDidBecomeKeyNotification和UIWindowDidResignKeyNotification消息通知;
(2) UIRemoteKeyboardWindow键盘弹起不会改变keyWindow,它的windowLevel为10000001的一个window,它的唤起会触发UIWindowDidBecomeVisibleNotification和UIWindowDidBecomeHiddenNotification消息通知,说明它是通过设置hidden来控制显示的;
(3) _UIAlertControllerShimPresenterWindow是已经废弃的UIAlertView的window,它会触发UIWindowDidBecomeKeyNotification和UIWindowDidResignKeyNotification消息,因此也会改变keyWindow;
(4) 第三方QQ分享(手机卸载QQ软件,弹出登录框场景),有时会触发UIWindowDidBecomeKeyNotification和UIWindowDidResignKeyNotification消息回调,说明此时触发了keywindow的切换;
2、验证与测试代码
针对上面提到的几种场景,测试demo代码如下:
GitHub - Leon0206/XYWindowTestProject: that is my window test project.
三、注意事项与使用建议
1、如果触发了keyWindow的切换,需要注意[UIApplication sharedApplication].keyWindow.rootViewController取值的变化;
2、如果你自定义了UIWindow(重写了UIWindow),你需要自己管理它,设置合理的windowLevel以及及时的清理;
3、如果你的应用对UIWindow有较为复杂的操作,建议可以用单例进行统一管理;
请关注个人公众号: