What is the difference between UIApplication.sharedApplication.delegate.window and UIApplication.sharedApplication.keyWindow?

StackOverflow https://stackoverflow.com/questions/21698482

Question

Can anyone help me understand the difference between the following two lines:

[UIApplication.sharedApplication.delegate.window addSubview:myView];
[UIApplication.sharedApplication.keyWindow addSubview:myView];
Was it helpful?

Solution 2

They could be the same on iOS. When they are different, usually you are presenting another window other than the app delegate's main window. Your app can have many windows but only the keyWindow is the window that is visible on the screen and receiving events (example could be a UIAlert when visible and receiving events it is the keywindow) reference: https://developer.apple.com/library/content/documentation/WindowsViews/Conceptual/WindowAndScreenGuide/WindowScreenRolesinApp/WindowScreenRolesinApp.html

from the documentation:

  • For UIApplication.sharedApplication.delegate.window:

The window to use when presenting a storyboard. This property contains the window used to present the app’s visual content on the device’s main screen.

i.e this is the property window that you have in your AppDelegate.h file.

  • For UIApplication.sharedApplication.keyWindow:

This property holds the UIWindow object in the windows array that is most recently sent the makeKeyAndVisible message.

On iOS you call makeKeyAndVisible in your AppDelegate.m inside

application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

You made the created appDelegate window the keyWindow. Usually, bank apps switch the key window when the app is put in the background to protect the users sensitive information when the home button is doubled tapped and switch back to the main delegate window when the app is in foreground.

This answer is in collaboration with: @SipkeSchoorstra, @D-Mx and @andyDarwin

OTHER TIPS

For most uses, they will be the same… but not always.

[UIApplication sharedApplication].keyWindow is the window which is currently being displayed on the device. This is normally your application's window, but could be a system window.

[UIApplication sharedApplication].delegate.window is the window your application is expected to use.

Which one should be used? Well that all depends on context.

If you are updating part of your application, then you should add views to your application's window. This is almost always what you want to do.

Personally, I always use [[UIApplication sharedApplication].delegate.window addSubview:view] or [self.view.window addSubView:view] (within UIViewController) when I need to add a view directly to the window.

There might be some times when you want to present a view to the window currently being displayed, regardless if the window belongs to your application or is some system window. I've not run into that situation.

Basheer_CAD's answer is not right. They are not always the same in iOS.

Jeffery Thomas's answer is right and let me provide a concrete example.

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"keyWindow --------> %@",[UIApplication sharedApplication].keyWindow.rootViewController);
    NSLog(@"delegate.window --> %@",[UIApplication sharedApplication].delegate.window.rootViewController);
    NSLog(@"self.view.window -> %@",self.view.window.rootViewController);
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"title" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:nil];
    [alert show];
    NSLog(@"keyWindow --------> %@",[UIApplication sharedApplication].keyWindow.rootViewController);
    NSLog(@"delegate.window --> %@",[UIApplication sharedApplication].delegate.window.rootViewController);
    NSLog(@"self.view.window -> %@",self.view.window.rootViewController);
}

The output is:

keyWindow --------> (null)
delegate.window --> <ViewController: 0x10030c0e0>
self.view.window -> (null)
keyWindow --------> <UIApplicationRotationFollowingController: 0x100204510>
delegate.window --> <ViewController: 0x10030c0e0>
self.view.window -> <ViewController: 0x10030c0e0>

When viewDidLoad, actually the window is not ready yet, so there is nothing for the system window. UIAlertView may dominate the window, so you cannot get the window you want.

The simplest setup is to just have one UIWindow. Usually that window is kept as a property on your app delegate. The keyWindow 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. So if you add a 2nd window and make it the keyWindow (via [window makeKeyAndVisible]), your lines return different windows!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top