UIWindow 详解及使用场景

时间:2021-11-04 02:02:43

首先来看一下UIWindow 继承关系

UIView的功能 

负责渲染区域的内容,并且响应该区域内发生的触摸事件

UIWindow

在iOS App中,UIWindow是最顶层的界面内容,我们使用UIWindow和UIView来呈现界面。UIWindow并不包含任何默认的内容,但是它被当作UIView的容器,用于放置应用中所有的UIView。

从继承关系来看,UIWindow继承自UIView,所以UIWindow除了具有UIView的所有功能之外,还增加了一些特有的属性和方法,而我们最常用的方法,就是在App刚启动时,调用UIWindow的rootViewController(必须指定根控制器) 和 makeKeyAndVisible方法

状态栏和键盘都是特殊的UIWindow。

UIWindow的主要作用有

1.作为UIView的最顶层容器,包含应用显示所有的UIView;

2.传递触摸消息和键盘事件给UIView;

UIWindow的层级:

UIWindow的层级由一个UIWindowLevel类型属性windowLevel,该属性指示了UIWindow的层级,windowLevel有三种可取值。

并且层级是可以做加减的self.window.windowLevel = UIWindowLevelAlert+1;

UIKIT_EXTERN const UIWindowLevel UIWindowLevelNormal; UIKIT_EXTERN const UIWindowLevel UIWindowLevelAlert; UIKIT_EXTERN const UIWindowLevel UIWindowLevelStatusBar __TVOS_PROHIBITED;

Normal ,StatusBar,Alert.输出他们三个层级的值,我们发现从左到右依次是0,1000,,2000,也就是说Normal级别是最低的,StatusBar处于中级,Alert级别最高。而通常我们的程序的界面都是处于Normal这个级别的,系统顶部的状态栏应该是处于StatusBar级别,提醒用户等操作位于Alert级别。根据window显示级别优先原则,级别高的会显示在最上层,级别低的在下面,我们程序正常显示的view在最底层;

四个关于window变化的通知

UIKIT_EXTERN NSNotificationName const UIWindowDidBecomeVisibleNotification; // nil UIKIT_EXTERN NSNotificationName const UIWindowDidBecomeHiddenNotification; // nil UIKIT_EXTERN NSNotificationName const UIWindowDidBecomeKeyNotification; // nil UIKIT_EXTERN NSNotificationName const UIWindowDidResignKeyNotification; // nil

这四个通知对象中的object都代表当前已显示(隐藏),已变成keyWindow(非keyWindow)的window对象,其中的userInfo则是空的。于是我们可以注册这个四个消息,再打印信息来观察keyWindow的变化以及window的显示,隐藏的变动 . 变成keywindow 的流程是这样的(默认的window -->点击弹出AlertView)

1.程序默认的window先显示出来

2.默认的window再变成keywindow 

3.AlertView 的window显示出来

4.默认的window变成keywindow

5.最终AlertView的window变成keywindow 

根据测试我们同时可以知道默认的window的level是0,即normal级别;AlertView的window的level是1996,比Alert级别稍微低了一点儿。同时我们可以看出ActionSheet的window的level是2001; 键盘window 的level是最高的在一切之上(我测试的是不管level 设置为多少都在键盘window 的下面)

当我们点击ActionSheet cancel的时候,我们会看到流程

1.首先ActionSheet 的window变成非keyWindow

2.程序默认的window变成keywindow 

3.ActionSheet 的window隐藏掉

弹出AlertView和ActionSheet的时候系统会帮你改变keyWindow  但是当弹出键盘的时候keyWindow是不变的!

下面有说keyWindow是用来接收键盘以及非触摸类的消息(文档有误 是指点击事件等 不是keywindow 也是可以接受事件的消息的)

keyWindow 

当前app可以打开的多个window 如系统状态栏其实就是一个window ,程序启动的时候创建的默认的window ,弹出键盘也是一个window ,alterView 弹框也是window 。但是keyWindow只有一个 ,一般情况下就是我们程序启动时设置的默认的window

官方文档中是这样解释的 “The key window is the one that is designated to receive keyboard and other non-touch related events. Only one window at a time may be the key window." 翻译过来就是说,keyWindow是指定的用来接收键盘以及非触摸类的消息,而且程序中每一个时刻只能有一个window是keyWindow。

文档有误:app可以打开的多个window 每个里面加入都加入UITextField  和点击事件 发现 都可以处理事件和接受键盘消息

问题一:一个应用程序只能有一个主窗口,如果程序中创建了两个Window,那么谁是主窗口?