我使用核心数据与云工具包,因此要检查iCloud用户状态在应用程序启动。如果出现问题,我想向用户发出一个对话框,我使用UIApplication.shared.keyWindow?. rootviewcontroller ?.present(…)到目前为止。
在Xcode 11 beta 4中,现在有一个新的弃用消息,告诉我:
'keyWindow'在iOS 13.0中已弃用:不应该用于支持多个场景的应用程序,因为它在所有连接的场景中返回一个键窗口
我应该如何呈现对话呢?
我使用核心数据与云工具包,因此要检查iCloud用户状态在应用程序启动。如果出现问题,我想向用户发出一个对话框,我使用UIApplication.shared.keyWindow?. rootviewcontroller ?.present(…)到目前为止。
在Xcode 11 beta 4中,现在有一个新的弃用消息,告诉我:
'keyWindow'在iOS 13.0中已弃用:不应该用于支持多个场景的应用程序,因为它在所有连接的场景中返回一个键窗口
我应该如何呈现对话呢?
当前回答
对于iOS 16,我使用了以下方法:
let keyWindow = UIApplication.shared.currentUIWindow()?.windowScene?.keyWindow
其他回答
我为一个视图分配了一个新窗口,并设置它[newWindow makeKeyAndVisible]; 当完成使用时,设置它[newWindow resignKeyWindow]; 然后尝试通过[UIApplication sharedApplication]. keywindow直接显示原始的键-窗口。
在iOS 12上一切正常,但在iOS 13上原始的键窗口不能正常显示。它显示整个白色屏幕。
我通过以下方法解决了这个问题:
UIWindow *mainWindow = nil;
if ( @available(iOS 13.0, *) ) {
mainWindow = [UIApplication sharedApplication].windows.firstObject;
[mainWindow makeKeyWindow];
} else {
mainWindow = [UIApplication sharedApplication].keyWindow;
}
如果你的应用还没有更新到采用基于场景的应用生命周期,另一种获得活动窗口对象的简单方法是通过UIApplicationDelegate:
let window = UIApplication.shared.delegate?.window
let rootViewController = window??.rootViewController
理想情况下,由于它已经被弃用,我建议你将窗口存储在SceneDelegate中。但是,如果您确实想要一个临时的解决方案,您可以创建一个过滤器并像这样检索keyWindow。
let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
一个UIApplication扩展:
extension UIApplication {
/// The app's key window taking into consideration apps that support multiple scenes.
var keyWindowInConnectedScenes: UIWindow? {
return windows.first(where: { $0.isKeyWindow })
}
}
用法:
let myKeyWindow: UIWindow? = UIApplication.shared.keyWindowInConnectedScenes
iOS 16,兼容至iOS 15
由于这个帖子在三年后仍有流量,我想分享我认为目前功能最优雅的解决方案。它也适用于SwiftUI。
UIApplication
.shared
.connectedScenes
.compactMap { ($0 as? UIWindowScene)?.keyWindow }
.first
iOS 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指出这一点!
最初的回答:
在matt的精彩回答基础上稍作改进,这个回答更简单、更简短、更优雅:
UIApplication.shared.windows.first { $0.isKeyWindow }