Can anyone help me understand the difference between the following two lines:
[UIApplication.sharedApplication.delegate.window addSubview:myView];
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.
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!
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.
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:
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.
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