我使用核心数据与云工具包,因此要检查iCloud用户状态在应用程序启动。如果出现问题,我想向用户发出一个对话框,我使用UIApplication.shared.keyWindow?. rootviewcontroller ?.present(…)到目前为止。

在Xcode 11 beta 4中,现在有一个新的弃用消息,告诉我:

'keyWindow'在iOS 13.0中已弃用:不应该用于支持多个场景的应用程序,因为它在所有连接的场景中返回一个键窗口

我应该如何呈现对话呢?


当前回答

理想情况下,由于它已经被弃用,我建议你将窗口存储在SceneDelegate中。但是,如果您确实想要一个临时的解决方案,您可以创建一个过滤器并像这样检索keyWindow。

let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first

其他回答

试试这个:

UIApplication.shared.windows.filter { $0.isKeyWindow }.first?.rootViewController!.present(alert, animated: true, completion: nil)

当.foregroundActive场景为空时,我遇到了这个问题

这是我的变通办法

public extension UIWindow {
    @objc
    static var main: UIWindow {
        // Here we sort all the scenes in order to work around the case
        // when no .foregroundActive scenes available and we need to look through
        // all connectedScenes in order to find the most suitable one
        let connectedScenes = UIApplication.shared.connectedScenes
            .sorted { lhs, rhs in
                let lhs = lhs.activationState
                let rhs = rhs.activationState
                switch lhs {
                case .foregroundActive:
                    return true
                case .foregroundInactive:
                    return rhs == .background || rhs == .unattached
                case .background:
                    return rhs == .unattached
                case .unattached:
                    return false
                @unknown default:
                    return false
                }
            }
            .compactMap { $0 as? UIWindowScene }

        guard connectedScenes.isEmpty == false else {
            fatalError("Connected scenes is empty")
        }
        let mainWindow = connectedScenes
            .flatMap { $0.windows }
            .first(where: \.isKeyWindow)

        guard let window = mainWindow else {
            fatalError("Couldn't get main window")
        }
        return window
    }
}

通常使用

斯威夫特5

UIApplication.shared.windows.filter {$0.isKeyWindow}.first

另外,在UIViewController中:

self.view.window

视图。窗口是当前场景的窗口

WWDC 2019:

关键的窗口 手动跟踪窗口

在iPad上介绍多个Windows - WWDC 2019 -视频-苹果开发人员 支持iPad上的多个Windows |苹果开发者文档

对于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;
}