我在Cloud中使用核心数据,因此在应用程序启动期间必须检查iCloud用户状态。如果出现问题,我想向用户发出一个对话框,到目前为止我使用UIApplication.shared.keyWindow?.rootViewController?.present(...)进行对话。
在Xcode 11 beta 4中,现在有一条新的弃用消息,告诉我:
“keyWindow”在iOS 13.0中被否决:不应用于支持多个场景的应用程序,因为它在所有连接的场景中返回一个关键窗口
我该如何呈现对话呢?
发布于 2019-07-23 17:58:26
这是我的解决办法:
let keyWindow = UIApplication.shared.connectedScenes
.filter({$0.activationState == .foregroundActive})
.compactMap({$0 as? UIWindowScene})
.first?.windows
.filter({$0.isKeyWindow}).first例如:
keyWindow?.endEditing(true)发布于 2019-09-12 02:40:24
编辑我在这里提出的建议在iOS 15中被否决了。那么现在呢?嗯,如果一个应用程序没有自己的多个窗口,我认为被接受的现代方式应该是获取应用程序的第一个connectedScenes,强制使用一个UIWindowScene,然后打开它的第一个窗口。但这几乎正是被接受的答案所做的!因此,我的解决办法在这一点上感到相当无力。然而,出于历史原因,我会让它站稳脚跟。
公认的答案,虽然巧妙,但可能过于详细。您可以得到更简单得多的完全相同的结果:
UIApplication.shared.windows.filter {$0.isKeyWindow}.first我还要提醒大家,不应过分严肃地对待keyWindow的反对意见。完整的警告消息如下:
“keyWindow”在iOS 13.0中被否决:不应用于支持多个场景的应用程序,因为它在所有连接的场景中返回一个关键窗口
因此,如果您不支持iPad上的多个窗口,则不反对继续使用keyWindow。
发布于 2019-09-20 16:10:39
iOS 16,兼容到iOS 15
三年后,随着这个线程的流量不断增加,我想分享我认为最优雅的解决方案和当前功能。它也适用于SwiftUI。
UIApplication
.shared
.connectedScenes
.compactMap { ($0 as? UIWindowScene)?.keyWindow }
.firstiOS 15和16,兼容iOS 13
UIApplication
.shared
.connectedScenes
.flatMap { ($0 as? UIWindowScene)?.windows ?? [] }
.first { $0.isKeyWindow }请注意,connectedScenes只在iOS 13之后才可用。如果您需要支持早期版本的iOS,则必须将其放在if #available(iOS 13, *)语句中。
更长但更容易理解的变体:
UIApplication
.shared
.connectedScenes
.compactMap { $0 as? UIWindowScene }
.flatMap { $0.windows }
.first { $0.isKeyWindow }iOS 13和14
下面的历史答案在iOS 15上仍然有效,但是应该被替换,因为不推荐使用UIApplication.shared.windows。感谢马特指出这一点!
原始答案:
对matt出色的回答稍作改进,这甚至更简单、更短、更优雅:
UIApplication.shared.windows.first { $0.isKeyWindow }https://stackoverflow.com/questions/57134259
复制相似问题