UIWindow 的学习
日常开发中,我们经常写这样的代码:
1 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { |
UIWindow的概念
UIWindow 是应用程序显示的背景,以及将接受的事件传递到视图的对象。
当我们打iPhone上的应用程序切换器,就会看到当前正在运行的应用程序的窗口。
大多数应用程序仅需要提供一个主窗口,即可在屏幕上显示应用内容,也可以根据需要创建其它窗口显示其它内容。
默认情况下,Xcode会提供应用程序的主窗口,即 Storyboards 会自动给 AppDelegate 的 window 属性提供值;如果不使用 Storyboards 则需要我们自己创建 window。
UIWindow 是一个特殊的 UIView,iOS 程序启动完毕后,创建的第一个视图控件就是 UIWindow,接着创建控制器的view,最后将控制器的View添加到 UIWindow 上,于是控制器的 View 就显示在屏幕上了。
UIWindow 的一些属性方法
对 keyWindow 的操作
1 | // 是否为 keyWindow |
创建 window 时,它的 hidden 值默认为 YES,因此不会显示。通过调用makeKeyAndVisible可以让 window 显示出来,或者直接设置 window?.isHidden = false 。
keywindow 用来接收键盘输入以及非触摸类的消息事件,程序中每个时刻只能有一个 UIWindow 是 keyWindow。如果某个 UIWindow 内部的文本框不能输入文字,可能是因为这个 UIWindow 不是 keyWindow。
在进行 keyWindow 操作时,系统会发送如下通知:
1 | UIWindow.didBecomeVisibleNotification |
rootViewController
设置了 window 的 rootViewController 后,会自动的把 View 添加到 window 中,并且负责管理 rootViewController 的生命周期。VC 会跟随 Window 的大小更改而更改
windowLevel 窗口在z轴上的位置
1 | var windowLevel: UIWindow.Level |
windowLevel 的值由 CGFloat 初始化获得,决定窗口在Z轴上显示的位置,默认值为 UIWindow.Level.normal(值为0),值越大越靠前显示
1 | UIWindow.Level.normal. ==> 0.0 |
将指定事件分发给View
1 | func sendEvent(_ event: UIEvent) |
UIApplication 调用该方法给 window 分发事件,window 再将事件分发到合适的目标,比如:可以调用此方法将自定义事件分派到窗口的事件响应程序链。
将坐标值与窗口的坐标系相互转换
1 | // 把该window中的一个坐标转换成在目标window中的坐标值 |
UIWindow 的一些操作
iOS中一些特殊的 window
1、UITextEffectsWindow,键盘所在的 window,iOS 8中新增的,其 windowLevel = 10;
2、UIRemoteKeyboardWindow,显示键盘按钮,iOS 9中新增的;
3、手机状态栏的UIStatusBarWindow, 属于系统级别, 不被App所持有;
4、UIAlertView 显示 _UIAlertControllerShimPresenterWindow;
获取应用程序的window
方式一:通过UIView
有时候window为null,原因是view没有完全加载完成或者在ViewDidload中才刚刚加载完,view的window属性无法被获取
1 | self.view.window |
方式二:通过UIApplication
1 | // 获取keyWindow,但不一定是显示在最前面的 |
iOS 13以后的UIWindow
1、创建一个新的 window 显示 Alert
1 | // 该window是全局变量 |
2、iOS 13及以后,若使用了SceneDelegate, 则在iOS13上获取 keyWindow 会得到nil,正确操作如下:
1 | UIApplication.shared.windows.first |
学习博客
看影成痴