美文网首页
UIWindow的使用,以及需要注意的坑

UIWindow的使用,以及需要注意的坑

作者: 小_梦 | 来源:发表于2021-03-29 16:43 被阅读0次

自定义创建Window

UIWindow是UIView的子类,UIView对象是通过方法addSubview:显示到父视图,但是window却不需要这样就能显示,只需要设置hidden为NO即可,实际中一个window对象真正显示到屏幕上还受到windowLevel影响

self.window1 = [[UIWindow alloc] initWithFrame:CGRectMake(0, 400, 150, 150)];
UIViewController *vc1 = [[UIViewController alloc] init];
vc1.view.backgroundColor = [UIColor redColor];
self.window1.rootViewController = vc1;
self.window1.windowLevel = 9;
[self.window1 makeKeyAndVisible];

  • 注意: [window makeKeyWindow];
    window.hidden = NO;
    等价与
    [self.window2 makeKeyAndVisible];

一个屏幕可以显示几个window?

理论上个数不限制,按需显示。屏幕顶部的状态栏、alert弹窗、键盘都是常见的window。

与window相关的几个知识点

1. windowLevel属性

默认值0.0,即系统定义的UIWindowLevelNormal。系统总共定义三种level,即如下

UIKIT_EXTERN const UIWindowLevel UIWindowLevelNormal = 0.f;
UIKIT_EXTERN const UIWindowLevel UIWindowLevelAlert = 2000.f;
UIKIT_EXTERN const UIWindowLevel UIWindowLevelStatusBar API_UNAVAILABLE(tvos) = 1000.f;

level越高在屏幕上显示层级越靠前,如果多个window设置相同的level,这时显示的层级就和设置hidden=NO的顺序有关,最后设置的会显示在最上层。

2. keyWindow

实际开发中我们常常会把一些显示级别高或者全局显示的视图放到keyWindow,通过[UIApplication sharedApplication].keyWindow获取使用。那keyWindow是什么,和其他window有什么不同?keyWindow即主窗口,参考官方文档说明,在程序运行期间只会存在一个主窗口,而且主窗口可以接收键盘事件及非触摸事件。接收键盘事件好理解,什么是非触摸事件呢?原文有相关描述

Whereas touch events are delivered to the window in which the touch occurred, events that don’t have an associated coordinate value are delivered to the key window.

英文能力有限,姑且理解为触摸事件传递到当前触摸的window,同时会把这个触摸事件传递到主窗口,但这个触摸事件传递时不会带着与坐标系相关的值。这里非触摸即没有touch主窗口,但依然可以接收到触摸事件。
事实上任何window都可以设置为keyWindow,如果只是使用自定window展示alert信息或者toast信息,没有必要设置;如果alert里需要输入信息,那就必须设置。
设置keyWindow的方法有两个,即

- (void)makeKeyWindow;
- (void)makeKeyAndVisible; 

UIApplication.sharedApplication.delegate.window和UIApplication.sharedApplication.keyWindow有什么区别?

  1. [UIApplication sharedApplication].keyWindow
    是设备上当前正在显示的窗口。这通常是您应用程序的窗口,但也可能是系统窗口
  2. [UIApplication sharedApplication].delegate.window
    是AppDelegate中定义的属性窗口,是主window;
    @property (strong, nonatomic) UIWindow *window;
  3. [UIApplication sharedApplication].windows.firstObject
    等价于
    [UIApplication sharedApplication].delegate.window
  4. [UIApplication sharedApplication].windows.lastObject
  5. [[UIApplication sharedApplication]windows].lastObject
    用来获取当前屏幕上最上层的一个UIWindow,但有可能不是当前的window
- (void)alertView {
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"测试" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"确认", nil];
    [alertView show];
    
//    UIWindow *window = [UIApplication sharedApplication].keyWindow; //是上面alert的window
    UIWindow *window = [UIApplication sharedApplication].delegate.window;// 是AppDelegate中定义的属性窗口
    UILabel *tempLabel =[[UILabel alloc]initWithFrame:CGRectMake(150, 150, 100, 20)];
    tempLabel.font = [UIFont systemFontOfSize:16];
    tempLabel.backgroundColor = [UIColor purpleColor];
    tempLabel.text = @"测试window";
    
    [window addSubview:tempLabel];
    
}
  • 注意:UIWindow *window = [UIApplication sharedApplication].keyWindow,如果使用这个的时候,下面的tempLabel就会添加到UIAlertView所在的_UIAlertControllerShimPresenterWindow层,当alert消失的时候,对应的windows和tempLabel都会释放

总结:

https://developer.apple.com/documentation/uikit/uiwindow?language=objc
官方参考文档 - 《Multiple Display Programming Guide for iOS》Understanding Windows and Screens

相关文章

网友评论

      本文标题:UIWindow的使用,以及需要注意的坑

      本文链接:https://www.haomeiwen.com/subject/bkbbhltx.html