UIApplication sharedApplication - keyWindow is nil

2019-01-15 05:15发布

I want to convert a CGPoint from my UIView to UIWindow coordinates and have realized that UIApplication keyWindow is always nil; why is this?

I have tried the convertPoint:toView: method from UIView.

Please see this sample code I tried in the view controller in a template of Xcode (View application):

- (void)viewDidLoad {
    [super viewDidLoad];
    UIView *test =  [[UIView alloc] initWithFrame:CGRectMake(40,40,250,250)];
    [test setBackgroundColor:[UIColor redColor]];
    [self.view addSubview:test];

    CGPoint p = CGPointMake(100, 100);
    CGPoint np;

    np = [test convertPoint:p toView:[[UIApplication sharedApplication] keyWindow]];
    NSLog(@"p:%@ np:%@", NSStringFromCGPoint(p), NSStringFromCGPoint(np));

    AppDelegate *appDel =  (AppDelegate *)[UIApplication sharedApplication].delegate;

    np = [test convertPoint:p toView:[appDel window]];
    NSLog(@"p:%@ np:%@", NSStringFromCGPoint(p), NSStringFromCGPoint(np));

    np = [test convertPoint:p toView:nil];
    NSLog(@"p:%@ np:%@", NSStringFromCGPoint(p), NSStringFromCGPoint(np));

    [test release];

    if(![[UIApplication sharedApplication] keyWindow])
        NSLog(@"window was nil");
}

and I get:

p:{100, 100} np:{100, 100}
p:{100, 100} np:{140, 160}
p:{100, 100} np:{100, 100}
window was nil

I can convert it but only when I access the window through the app delegate. And not UIApplication. According to the documentation, keyWindow should work here, but is nil. Why is this?

3条回答
在下西门庆
2楼-- · 2019-01-15 05:53

I noticed that after having started the Guided Access, the keyWindow property on [UIApplication sharedApplication] appears to be nil.

It happened to me only on iOS7 when starting the Guided Access Mode for the first time after having enabled it in Settings > General > Guided Access, so the starting GAM view is actually displayed and not by-passed.

Since this Apple API seems buggy, I solved using the following code to retrieve the window I'm looking for.

NSArray *windows = [[UIApplication sharedApplication] windows];
if ([windows count]) {
    return windows[0];
}
return nil;

Instead of

[[UIApplication sharedApplication] keyWindow];

maybe you could also try using

[[[UIApplication sharedApplication] delegate] window];

as iWasRobbed pointed out but it wasn't working for me as the rootViewController property isn't reachable this way.

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-01-15 06:03

Easiest way is to get the window from the app delegate instead:

UIWindow *keyWindow = [[[UIApplication sharedApplication] delegate] window];
// Do something with the window now
查看更多
forever°为你锁心
4楼-- · 2019-01-15 06:09

This code was executed before [window makeKeyAndVisible]; which is inside the app delegate. So, no wonder why keyWindow was nil yet.

查看更多
登录 后发表回答