How to resolve: 'keyWindow' was deprecated in iOS 13.0

跟風遠走 提交于 2019-11-26 12:26:51

问题


I\'m using Core Data with Cloud Kit, and have therefore to check the iCloud user status during application startup. In case of problems I want to issue a dialog to the user, and I do it using UIApplication.shared.keyWindow?.rootViewController?.present(...) up to now.

In Xcode 11 beta 4, there is now a new deprecation message, telling me:

\'keyWindow\' was deprecated in iOS 13.0: Should not be used for applications that support multiple scenes as it returns a key window across all connected scenes

How shall I present the dialog instead?


回答1:


This is my solution:

let keyWindow = UIApplication.shared.connectedScenes
        .filter({$0.activationState == .foregroundActive})
        .map({$0 as? UIWindowScene})
        .compactMap({$0})
        .first?.windows
        .filter({$0.isKeyWindow}).first

Usage e.g.:

keyWindow?.endEditing(true)



回答2:


The accepted answer, while ingenious, might be overly elaborate. You can get exactly the same result much more simply:

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

I would also caution that the deprecation of keyWindow should not be taken overly seriously. The full warning message reads:

'keyWindow' was deprecated in iOS 13.0: Should not be used for applications that support multiple scenes as it returns a key window across all connected scenes

So if you are not supporting multiple windows on iPad there is no objection to going ahead and continuing to use keyWindow.




回答3:


Improving slightly on matt's excellent answer, this is even simpler, shorter, and more elegant:

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



回答4:


Ideally, since it has been deprecated I would advice you to store the window in the SceneDelegate. However if you do want a temporary workaround, you can create a filter and retrieve the keyWindow just like this.

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



回答5:


For an objective C solution

+(UIWindow*)keyWindow
{
    UIWindow        *foundWindow = nil;
    NSArray         *windows = [[UIApplication sharedApplication]windows];
    for (UIWindow   *window in windows) {
        if (window.isKeyWindow) {
            foundWindow = window;
            break;
        }
    }
    return foundWindow;
}



回答6:


A UIApplication extension:

extension UIApplication {

    /// The app's key window taking into consideration apps that support multiple scenes.
    var keyWindowInConnectedScenes: UIWindow? {
        return windows.first(where: { $0.isKeyWindow })
    }

}

Usage:

let myKeyWindow: UIWindow? = UIApplication.shared.keyWindowInConnectedScenes



回答7:


I met the same problem. I alloced a newWindow for a view, and set it [newWindow makeKeyAndVisible]; When finished using it, set it [newWindow resignKeyWindow]; and then try to show the original key-window directly by [UIApplication sharedApplication].keyWindow.

Everything is all right on iOS 12, but on iOS 13 the original key-window can't been normal shown. It shows a whole white screen.

I solved this problem by:

UIWindow *mainWindow = nil;
if ( @available(iOS 13.0, *) ) {
   mainWindow = [UIApplication sharedApplication].windows.firstObject;
   [mainWindow makeKeyWindow];
} else {
    mainWindow = [UIApplication sharedApplication].keyWindow;
}

Hope it helps.



来源:https://stackoverflow.com/questions/57134259/how-to-resolve-keywindow-was-deprecated-in-ios-13-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!