iOS开发之KeyWindow获取的时机

2018-01-15  本文已影响0人  KODIE

何为KeyWindow

当前正在显示的Window为KeyWindow,获取的代码:

UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
NSLog(@"keyWindow = %@",keyWindow);

看下打印结果:

2018-01-14 23:18:33.716330+0800 KeyWindowDemo[59456:6552154] keyWindow = (null)

疑问来了,怎么会获取不到KeyWindow呢?

获取KeyWindow的时机

我直接说时机吧,KeyWindow一定要等到其根控制器viewWillAppear:方法走完,才能顺利走完makeKeyAndVisible这句代码的。

大家可以看下我打印位置和输出结果就知道了:
打印位置截图如下:


[图片上传中...(Snip20180115_5.png-d48be7-1515981265755-0)] Snip20180115_5.png

输出结果如下:

2018-01-15 09:51:10.597680+0800 KeyWindowDemo[61266:6675333] 成为KeyWindow之前 (null)
2018-01-15 09:51:10.600438+0800 KeyWindowDemo[61266:6675333] viewDidLoad keyWindow = (null)
2018-01-15 09:51:10.600735+0800 KeyWindowDemo[61266:6675333] viewWillAppear keyWindow = (null)
2018-01-15 09:51:10.602867+0800 KeyWindowDemo[61266:6675333] 成为KeyWindow之后 <UIWindow: 0x7feef060b190; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x60000025c0b0>; layer = <UIWindowLayer: 0x60000022b3c0>>
2018-01-15 09:51:10.605671+0800 KeyWindowDemo[61266:6675333] viewDidAppear keyWindow = <UIWindow: 0x7feef060b190; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x60000025c0b0>; layer = <UIWindowLayer: 0x60000022b3c0>>

大家也就知道KeyWindow的获取时机了。还有一个问题,那是不是我在其他控制器创建的时候的viewDidLoad方法和viewWillAppear方法内也获取不到呢?请看:
先创建一个PushViewController

//PushViewController.h
#import <UIKit/UIKit.h>

@interface PushViewController : UIViewController

@end
//PushViewController.m
#import "PushViewController.h"

@interface PushViewController ()

@end

@implementation PushViewController

- (void)viewDidLoad {
    [super viewDidLoad];
 
    self.view.backgroundColor = [UIColor whiteColor];
    
    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
    NSLog(@"PushViewController viewDidLoad keyWindow = %@",keyWindow);
}

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    
    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
    NSLog(@"PushViewController viewWillAppear keyWindow = %@",keyWindow);
}

- (void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    
    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
    NSLog(@"PushViewController viewDidAppear keyWindow = %@",keyWindow);
}

@end

在ViewController.m中部署创建按钮的代码,然后点击按钮跳转到PushViewController

PushViewController *pvc = [[PushViewController alloc] init];
[self presentViewController:pvc animated:YES completion:nil];

看KeyWindow的打印结果:

2018-01-15 10:05:37.712062+0800 KeyWindowDemo[61616:6696661] PushViewController viewDidLoad keyWindow = <UIWindow: 0x7fb9d8507860; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x6000004418f0>; layer = <UIWindowLayer: 0x60400003f1a0>>
2018-01-15 10:05:37.714975+0800 KeyWindowDemo[61616:6696661] PushViewController viewWillAppear keyWindow = <UIWindow: 0x7fb9d8507860; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x6000004418f0>; layer = <UIWindowLayer: 0x60400003f1a0>>
2018-01-15 10:05:38.218593+0800 KeyWindowDemo[61616:6696661] PushViewController viewDidAppear keyWindow = <UIWindow: 0x7fb9d8507860; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x6000004418f0>; layer = <UIWindowLayer: 0x60400003f1a0>>

所以只要UIApplication已经有了KeyWindow了其他地方就都能获取了,但是如果在做KeyWindow切换的时候呢也是要注意时机的。

注意

知道时机之后我们如果要需要在窗口上显示一个Alert,并且把这个封装成一个功能来做的话,那我们可能还不能直接用获取KeyWindow的方式来获取,因为KeyWindow有可能获取不到,那我们还有一个办法是直接拿到Appdelegate的window属性,然后直接加在这个window上面,但是也有一个问题就是你必须导入这个Appdelegate这个类的头文件,如果我Appdelegate换成自定义的名字呢,那这样就换到别的工程还得改,另外当window切换的时候可能导致也不能用,所以此处还有另外一种方式:

UIWindow *lastWindow = [[[UIApplication sharedApplication] windows] lastObject];
NSLog(@"lastWindow = %@",lastWindow);

里面有一个专门弹框的一个工具类,大家可以下载DEMO看下 DEMO传送门~~~
以上!!!

呵呵.gif
上一篇下一篇

猜你喜欢

热点阅读