UIApplication.sharedApplication.delegate.window 和 UIApplication.sharedApplication.keyWindow 有啥区别?
Posted
技术标签:
【中文标题】UIApplication.sharedApplication.delegate.window 和 UIApplication.sharedApplication.keyWindow 有啥区别?【英文标题】:What is the difference between UIApplication.sharedApplication.delegate.window and UIApplication.sharedApplication.keyWindow?UIApplication.sharedApplication.delegate.window 和 UIApplication.sharedApplication.keyWindow 有什么区别? 【发布时间】:2014-02-11 09:56:47 【问题描述】:谁能帮我理解以下两行之间的区别:
[UIApplication.sharedApplication.delegate.window addSubview:myView];
[UIApplication.sharedApplication.keyWindow addSubview:myView];
【问题讨论】:
【参考方案1】:对于大多数用途,它们将是相同的……但并非总是如此。
[UIApplication sharedApplication].keyWindow
是当前在设备上显示的窗口。这通常是您应用程序的窗口,但也可以是系统窗口。
[UIApplication sharedApplication].delegate.window
是您的应用程序预期使用的窗口。
应该使用哪一个?好吧,这一切都取决于上下文。
如果您要更新应用程序的一部分,那么您应该将视图添加到应用程序的窗口中。这几乎总是您想要做的。
就个人而言,当我需要直接向窗口添加视图时,我总是使用[[UIApplication sharedApplication].delegate.window addSubview:view]
或[self.view.window addSubView:view]
(在UIViewController
内)。
有时您可能希望向当前正在显示的窗口呈现视图,无论该窗口属于您的应用程序还是某个系统窗口。我没有遇到过这种情况。
【讨论】:
由于您不知道最后出现的是哪个屏幕...当您收到远程通知时使用keyWindow
显示警报是否会更好?我说的是早于 ios10 的 iOS 版本,你没有 willPresent
?【参考方案2】:
它们在 iOS 上可能是相同的。当它们不同时,通常您会呈现除应用程序委托的主窗口之外的另一个窗口。您的应用可以有多个窗口,但只有 keyWindow
是在屏幕上可见并接收事件的窗口(示例可能是 UIAlert 可见并接收事件时它是键窗口)参考:https://developer.apple.com/library/content/documentation/WindowsViews/Conceptual/WindowAndScreenGuide/WindowScreenRolesinApp/WindowScreenRolesinApp.html
来自文档:
对于UIApplication.sharedApplication.delegate.window
:
呈现故事板时使用的窗口。该属性包含 用于在设备上显示应用程序视觉内容的窗口 主屏幕。
即这是您在AppDelegate.h
文件中拥有的属性window
。
UIApplication.sharedApplication.keyWindow
:
此属性在 windows 数组中保存 UIWindow 对象,即 最近发送了 makeKeyAndVisible 消息。
在 iOS 上,您在 AppDelegate.m
内部调用 makeKeyAndVisible
application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
您将创建的 appDelegate 窗口设为 keyWindow。通常,银行应用在后台切换按键窗口,以保护用户在双击主页按钮时的敏感信息,并在应用处于前台时切换回主代理窗口。
此答案与@SipkeSchoorstra、@D-Mx 和@andyDarwin 合作
【讨论】:
投反对票,因为这不正确,请参阅 Jeffrey Thomas 和 Andy Darwin 的回答。 @SipkeSchoorstra 感谢您的反馈,答案已更新。 这是错误的。不仅 keyWindow 是可见的,例如警报使用单独的窗口来显示。当一个窗口当前正在接收键盘和非触摸相关事件时,它被认为是关键窗口。见developer.apple.com/library/content/documentation/WindowsViews/… 嘿@D-Mx,是的,看起来我忘了提到关键窗口是可见的并且正在接收事件,刚刚更新以包含它。我想说答案没有错,但不完整,感谢您帮助使 *** 变得友好和协作:)【参考方案3】:Basheer_CAD 的回答不对。它们在 iOS 中并不总是相同的。
Jeffery Thomas 的回答是正确的,让我提供一个具体的例子。
- (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);
输出是:
keyWindow --------> (null)
delegate.window --> <ViewController: 0x10030c0e0>
self.view.window -> (null)
keyWindow --------> <UIApplicationRotationFollowingController: 0x100204510>
delegate.window --> <ViewController: 0x10030c0e0>
self.view.window -> <ViewController: 0x10030c0e0>
viewDidLoad
时,实际上窗口还没有准备好,所以系统窗口什么都没有。 UIAlertView
可能主宰了窗口,所以你无法得到你想要的窗口。
【讨论】:
感谢您的反馈,请查看我的更新答案。因此,您的答案被赞成:)【参考方案4】:最简单的设置是只有一个UIWindow
。通常,该窗口作为您的应用程序委托的属性保留。 keyWindow
是指定接收键盘和其他与触摸无关的事件。一次只能有一个窗口是关键窗口。因此,如果您添加第二个窗口并将其设为keyWindow
(通过[window makeKeyAndVisible]
),您的行将返回不同的窗口!
【讨论】:
以上是关于UIApplication.sharedApplication.delegate.window 和 UIApplication.sharedApplication.keyWindow 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章