如何解决:'keyWindow' 在 iOS 13.0 中已弃用
How to resolve: 'keyWindow' was deprecated in iOS 13.0
我在 Cloud Kit 中使用 Core Data,因此必须在应用程序启动期间检查 iCloud 用户状态。如果出现问题,我想向用户发出一个对话框,到目前为止我使用 UIApplication.shared.keyWindow?.rootViewController?.present(...)
来做到这一点。
在 Xcode 11 beta 4 中,现在有一条新的弃用消息,告诉我:
'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
我应该如何显示对话框?
这是我的解决方案:
let keyWindow = UIApplication.shared.connectedScenes
.filter({[=10=].activationState == .foregroundActive})
.compactMap({[=10=] as? UIWindowScene})
.first?.windows
.filter({[=10=].isKeyWindow}).first
用法例如:
keyWindow?.endEditing(true)
编辑 我在此处提出的建议已在 iOS 中弃用 15. 那么现在怎么办?好吧,如果一个应用程序没有自己的多个 windows,我认为公认的现代方法是获取应用程序的第一个 connectedScenes
,强制到 UIWindowScene,然后获取它的第一个 window。但这几乎正是公认的答案所做的!所以我的解决方法在这一点上感觉相当无力。但是,由于历史原因,我会保留它。
接受的答案虽然巧妙,但可能过于详尽。您可以更简单地获得完全相同的结果:
UIApplication.shared.windows.filter {[=10=].isKeyWindow}.first
我还提醒大家不要过分认真地对待 keyWindow
的弃用。完整的警告消息如下:
'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
因此,如果您不支持 iPad 上的多个 windows,则不反对继续使用 keyWindow
。
iOS 15,向下兼容 iOS 13
UIApplication
.shared
.connectedScenes
.flatMap { ([=10=] as? UIWindowScene)?.windows ?? [] }
.first { [=10=].isKeyWindow }
请注意 connectedScenes
仅在 iOS 13 之后可用。如果您需要支持 iOS 的早期版本,则必须将其放在 if #available(iOS 13, *)
语句中.
更长但更容易理解的变体:
UIApplication
.shared
.connectedScenes
.compactMap { [=11=] as? UIWindowScene }
.flatMap { [=11=].windows }
.first { [=11=].isKeyWindow }
iOS 13 和 14
以下历史答案在 iOS 15 上仍然有效,但应该被替换,因为 UIApplication.shared.windows
已弃用。感谢@matt 指出这一点!
原回答:
在 matt 的出色回答上略有改进,这更简单、更短、更优雅:
UIApplication.shared.windows.first { [=12=].isKeyWindow }
理想情况下,由于它已被弃用,我建议您将 window 存储在 SceneDelegate 中。但是,如果您确实需要临时解决方法,您可以像这样创建一个过滤器并检索 keyWindow。
let window = UIApplication.shared.windows.filter {[=10=].isKeyWindow}.first
Objective-C 解决方案
+(UIWindow*)keyWindow
{
UIWindow *foundWindow = nil;
NSArray *windows = [[UIApplication sharedApplication]windows];
for (UIWindow *window in windows) {
if (window.isKeyWindow) {
foundWindow = window;
break;
}
}
return foundWindow;
}
我遇到了同样的问题。
我为视图分配了 newWindow
,并将其设置为 [newWindow makeKeyAndVisible];
使用完毕后,设置[newWindow resignKeyWindow];
然后尝试通过[UIApplication sharedApplication].keyWindow
.
直接显示原始密钥-window
在iOS12上一切正常,但在iOS13上无法正常显示原来的key-window。它显示了一个完整的白色屏幕。
我通过以下方式解决了这个问题:
UIWindow *mainWindow = nil;
if ( @available(iOS 13.0, *) ) {
mainWindow = [UIApplication sharedApplication].windows.firstObject;
[mainWindow makeKeyWindow];
} else {
mainWindow = [UIApplication sharedApplication].keyWindow;
}
希望对您有所帮助。
一个UIApplication
分机:
extension UIApplication {
/// The app's key window taking into consideration apps that support multiple scenes.
var keyWindowInConnectedScenes: UIWindow? {
return windows.first(where: { [=10=].isKeyWindow })
}
}
用法:
let myKeyWindow: UIWindow? = UIApplication.shared.keyWindowInConnectedScenes
NSSet *connectedScenes = [UIApplication sharedApplication].connectedScenes;
for (UIScene *scene in connectedScenes) {
if (scene.activationState == UISceneActivationStateForegroundActive && [scene isKindOfClass:[UIWindowScene class]]) {
UIWindowScene *windowScene = (UIWindowScene *)scene;
for (UIWindow *window in windowScene.windows) {
UIViewController *viewController = window.rootViewController;
// Get the instance of your view controller
if ([viewController isKindOfClass:[YOUR_VIEW_CONTROLLER class]]) {
// Your code here...
break;
}
}
}
}
灵感来自
的回答
let keyWindow = Array(UIApplication.shared.connectedScenes)
.compactMap { [=10=] as? UIWindowScene }
.flatMap { [=10=].windows }
.first(where: { [=10=].isKeyWindow })
这是一种向后兼容的检测方式 keyWindow
:
extension UIWindow {
static var key: UIWindow? {
if #available(iOS 13, *) {
return UIApplication.shared.windows.first { [=10=].isKeyWindow }
} else {
return UIApplication.shared.keyWindow
}
}
}
用法:
if let keyWindow = UIWindow.key {
// Do something
}
尝试一下:
UIApplication.shared.windows.filter { [=10=].isKeyWindow }.first?.rootViewController!.present(alert, animated: true, completion: nil)
通常使用
Swift 5
UIApplication.shared.windows.filter {[=10=].isKeyWindow}.first
此外,在UIViewController中:
self.view.window
view.window
当前 window 场景
WWDC 2019:
Key Windows
- Track windows manually
对于Objective-C
的解决方案
@implementation UIWindow (iOS13)
+ (UIWindow*) keyWindow {
NSPredicate *isKeyWindow = [NSPredicate predicateWithFormat:@"isKeyWindow == YES"];
return [[[UIApplication sharedApplication] windows] filteredArrayUsingPredicate:isKeyWindow].firstObject;
}
@end
许多开发人员要求 Objective C 代码来替代此弃用。您可以使用下面的代码来使用 keyWindow。
+(UIWindow*)keyWindow {
UIWindow *windowRoot = nil;
NSArray *windows = [[UIApplication sharedApplication]windows];
for (UIWindow *window in windows) {
if (window.isKeyWindow) {
windowRoot = window;
break;
}
}
return windowRoot;
}
我在 AppDelegate
class 中创建并添加了此方法作为 class 方法,并使用下面非常简单的方法使用它。
[AppDelegate keyWindow];
不要忘记在 AppDelegate.h class 中添加此方法,如下所示。
+(UIWindow*)keyWindow;
- (UIWindow *)mainWindow {
NSEnumerator *frontToBackWindows = [UIApplication.sharedApplication.windows reverseObjectEnumerator];
for (UIWindow *window in frontToBackWindows) {
BOOL windowOnMainScreen = window.screen == UIScreen.mainScreen;
BOOL windowIsVisible = !window.hidden && window.alpha > 0;
BOOL windowLevelSupported = (window.windowLevel >= UIWindowLevelNormal);
BOOL windowKeyWindow = window.isKeyWindow;
if(windowOnMainScreen && windowIsVisible && windowLevelSupported && windowKeyWindow) {
return window;
}
}
return nil;
}
如果你想在任何ViewController中使用它,那么你可以简单地使用。
self.view.window
Berni 的代码很好,但是当应用程序从后台返回时它不起作用。
这是我的代码:
class var safeArea : UIEdgeInsets
{
if #available(iOS 13, *) {
var keyWindow = UIApplication.shared.connectedScenes
.filter({[=10=].activationState == .foregroundActive})
.map({[=10=] as? UIWindowScene})
.compactMap({[=10=]})
.first?.windows
.filter({[=10=].isKeyWindow}).first
// <FIX> the above code doesn't work if the app comes back from background!
if (keyWindow == nil) {
keyWindow = UIApplication.shared.windows.first { [=10=].isKeyWindow }
}
return keyWindow?.safeAreaInsets ?? UIEdgeInsets()
}
else {
guard let keyWindow = UIApplication.shared.keyWindow else { return UIEdgeInsets() }
return keyWindow.safeAreaInsets
}
}
当 .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 { [=10=] as? UIWindowScene }
guard connectedScenes.isEmpty == false else {
fatalError("Connected scenes is empty")
}
let mainWindow = connectedScenes
.flatMap { [=10=].windows }
.first(where: \.isKeyWindow)
guard let window = mainWindow else {
fatalError("Couldn't get main window")
}
return window
}
}
如果您的应用尚未更新为采用基于场景的应用生命周期,另一种获取活动 window 对象的简单方法是通过 UIApplicationDelegate
:
let window = UIApplication.shared.delegate?.window
let rootViewController = window??.rootViewController
我有 answered the question on a duplicate feed,由于我在这里找不到提供尽可能多代码(已注释)的答案,这是我的贡献:
(在 Xcode 13.2.1 上使用 iOS 15.2 运行 测试)
extension UIApplication {
var keyWindow: UIWindow? {
// Get connected scenes
return UIApplication.shared.connectedScenes
// Keep only active scenes, onscreen and visible to the user
.filter { [=10=].activationState == .foregroundActive }
// Keep only the first `UIWindowScene`
.first(where: { [=10=] is UIWindowScene })
// Get its associated windows
.flatMap({ [=10=] as? UIWindowScene })?.windows
// Finally, keep only the key window
.first(where: \.isKeyWindow)
}
}
如果你想在键 UIWindow
中找到出现的 UIViewController
,这里是另一个你可能会发现有用的 extension
:
extension UIApplication {
var keyWindowPresentedController: UIViewController? {
var viewController = self.keyWindow?.rootViewController
// If root `UIViewController` is a `UITabBarController`
if let presentedController = viewController as? UITabBarController {
// Move to selected `UIViewController`
viewController = presentedController.selectedViewController
}
// Go deeper to find the last presented `UIViewController`
while let presentedController = viewController?.presentedViewController {
// If root `UIViewController` is a `UITabBarController`
if let presentedController = presentedController as? UITabBarController {
// Move to selected `UIViewController`
viewController = presentedController.selectedViewController
} else {
// Otherwise, go deeper
viewController = presentedController
}
}
return viewController
}
}
你可以把它放在任何你想要的地方,但我个人将它作为 extension
添加到 UIViewController
。
这让我可以添加更多有用的扩展,例如更容易呈现 UIViewController
的扩展:
extension UIViewController {
func presentInKeyWindow(animated: Bool = true, completion: (() -> Void)? = nil) {
DispatchQueue.main.async {
UIApplication.shared.keyWindow?.rootViewController?
.present(self, animated: animated, completion: completion)
}
}
func presentInKeyWindowPresentedController(animated: Bool = true, completion: (() -> Void)? = nil) {
DispatchQueue.main.async {
UIApplication.shared.keyWindowPresentedController?
.present(self, animated: animated, completion: completion)
}
}
}
如果您使用带有 'first_where' 规则的 SwiftLint 并且想停止交战:
UIApplication.shared.windows.first(where: { [=10=].isKeyWindow })
支持 iOS13 及更高版本。
要继续使用与旧 iOS 版本 UIApplication.shared.keyWindow
相似的语法,请创建此扩展:
extension UIApplication {
var mainKeyWindow: UIWindow? {
get {
if #available(iOS 13, *) {
return connectedScenes
.flatMap { ([=10=] as? UIWindowScene)?.windows ?? [] }
.first { [=10=].isKeyWindow }
} else {
return keyWindow
}
}
}
}
用法
if let keyWindow = UIApplication.shared.mainKeyWindow {
// Do Stuff
}
我已经解决了:
let scenes = UIApplication.shared.connectedScenes
let windowScene = scenes.first as? UIWindowScene
let window = windowScene?.windows.first
我在 Cloud Kit 中使用 Core Data,因此必须在应用程序启动期间检查 iCloud 用户状态。如果出现问题,我想向用户发出一个对话框,到目前为止我使用 UIApplication.shared.keyWindow?.rootViewController?.present(...)
来做到这一点。
在 Xcode 11 beta 4 中,现在有一条新的弃用消息,告诉我:
'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
我应该如何显示对话框?
这是我的解决方案:
let keyWindow = UIApplication.shared.connectedScenes
.filter({[=10=].activationState == .foregroundActive})
.compactMap({[=10=] as? UIWindowScene})
.first?.windows
.filter({[=10=].isKeyWindow}).first
用法例如:
keyWindow?.endEditing(true)
编辑 我在此处提出的建议已在 iOS 中弃用 15. 那么现在怎么办?好吧,如果一个应用程序没有自己的多个 windows,我认为公认的现代方法是获取应用程序的第一个 connectedScenes
,强制到 UIWindowScene,然后获取它的第一个 window。但这几乎正是公认的答案所做的!所以我的解决方法在这一点上感觉相当无力。但是,由于历史原因,我会保留它。
接受的答案虽然巧妙,但可能过于详尽。您可以更简单地获得完全相同的结果:
UIApplication.shared.windows.filter {[=10=].isKeyWindow}.first
我还提醒大家不要过分认真地对待 keyWindow
的弃用。完整的警告消息如下:
'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
因此,如果您不支持 iPad 上的多个 windows,则不反对继续使用 keyWindow
。
iOS 15,向下兼容 iOS 13
UIApplication
.shared
.connectedScenes
.flatMap { ([=10=] as? UIWindowScene)?.windows ?? [] }
.first { [=10=].isKeyWindow }
请注意 connectedScenes
仅在 iOS 13 之后可用。如果您需要支持 iOS 的早期版本,则必须将其放在 if #available(iOS 13, *)
语句中.
更长但更容易理解的变体:
UIApplication
.shared
.connectedScenes
.compactMap { [=11=] as? UIWindowScene }
.flatMap { [=11=].windows }
.first { [=11=].isKeyWindow }
iOS 13 和 14
以下历史答案在 iOS 15 上仍然有效,但应该被替换,因为 UIApplication.shared.windows
已弃用。感谢@matt 指出这一点!
原回答:
在 matt 的出色回答上略有改进,这更简单、更短、更优雅:
UIApplication.shared.windows.first { [=12=].isKeyWindow }
理想情况下,由于它已被弃用,我建议您将 window 存储在 SceneDelegate 中。但是,如果您确实需要临时解决方法,您可以像这样创建一个过滤器并检索 keyWindow。
let window = UIApplication.shared.windows.filter {[=10=].isKeyWindow}.first
Objective-C 解决方案
+(UIWindow*)keyWindow
{
UIWindow *foundWindow = nil;
NSArray *windows = [[UIApplication sharedApplication]windows];
for (UIWindow *window in windows) {
if (window.isKeyWindow) {
foundWindow = window;
break;
}
}
return foundWindow;
}
我遇到了同样的问题。
我为视图分配了 newWindow
,并将其设置为 [newWindow makeKeyAndVisible];
使用完毕后,设置[newWindow resignKeyWindow];
然后尝试通过[UIApplication sharedApplication].keyWindow
.
在iOS12上一切正常,但在iOS13上无法正常显示原来的key-window。它显示了一个完整的白色屏幕。
我通过以下方式解决了这个问题:
UIWindow *mainWindow = nil;
if ( @available(iOS 13.0, *) ) {
mainWindow = [UIApplication sharedApplication].windows.firstObject;
[mainWindow makeKeyWindow];
} else {
mainWindow = [UIApplication sharedApplication].keyWindow;
}
希望对您有所帮助。
一个UIApplication
分机:
extension UIApplication {
/// The app's key window taking into consideration apps that support multiple scenes.
var keyWindowInConnectedScenes: UIWindow? {
return windows.first(where: { [=10=].isKeyWindow })
}
}
用法:
let myKeyWindow: UIWindow? = UIApplication.shared.keyWindowInConnectedScenes
NSSet *connectedScenes = [UIApplication sharedApplication].connectedScenes;
for (UIScene *scene in connectedScenes) {
if (scene.activationState == UISceneActivationStateForegroundActive && [scene isKindOfClass:[UIWindowScene class]]) {
UIWindowScene *windowScene = (UIWindowScene *)scene;
for (UIWindow *window in windowScene.windows) {
UIViewController *viewController = window.rootViewController;
// Get the instance of your view controller
if ([viewController isKindOfClass:[YOUR_VIEW_CONTROLLER class]]) {
// Your code here...
break;
}
}
}
}
灵感来自
let keyWindow = Array(UIApplication.shared.connectedScenes)
.compactMap { [=10=] as? UIWindowScene }
.flatMap { [=10=].windows }
.first(where: { [=10=].isKeyWindow })
这是一种向后兼容的检测方式 keyWindow
:
extension UIWindow {
static var key: UIWindow? {
if #available(iOS 13, *) {
return UIApplication.shared.windows.first { [=10=].isKeyWindow }
} else {
return UIApplication.shared.keyWindow
}
}
}
用法:
if let keyWindow = UIWindow.key {
// Do something
}
尝试一下:
UIApplication.shared.windows.filter { [=10=].isKeyWindow }.first?.rootViewController!.present(alert, animated: true, completion: nil)
通常使用
Swift 5
UIApplication.shared.windows.filter {[=10=].isKeyWindow}.first
此外,在UIViewController中:
self.view.window
view.window
当前 window 场景
WWDC 2019:
Key Windows
- Track windows manually
对于Objective-C
的解决方案@implementation UIWindow (iOS13)
+ (UIWindow*) keyWindow {
NSPredicate *isKeyWindow = [NSPredicate predicateWithFormat:@"isKeyWindow == YES"];
return [[[UIApplication sharedApplication] windows] filteredArrayUsingPredicate:isKeyWindow].firstObject;
}
@end
许多开发人员要求 Objective C 代码来替代此弃用。您可以使用下面的代码来使用 keyWindow。
+(UIWindow*)keyWindow {
UIWindow *windowRoot = nil;
NSArray *windows = [[UIApplication sharedApplication]windows];
for (UIWindow *window in windows) {
if (window.isKeyWindow) {
windowRoot = window;
break;
}
}
return windowRoot;
}
我在 AppDelegate
class 中创建并添加了此方法作为 class 方法,并使用下面非常简单的方法使用它。
[AppDelegate keyWindow];
不要忘记在 AppDelegate.h class 中添加此方法,如下所示。
+(UIWindow*)keyWindow;
- (UIWindow *)mainWindow {
NSEnumerator *frontToBackWindows = [UIApplication.sharedApplication.windows reverseObjectEnumerator];
for (UIWindow *window in frontToBackWindows) {
BOOL windowOnMainScreen = window.screen == UIScreen.mainScreen;
BOOL windowIsVisible = !window.hidden && window.alpha > 0;
BOOL windowLevelSupported = (window.windowLevel >= UIWindowLevelNormal);
BOOL windowKeyWindow = window.isKeyWindow;
if(windowOnMainScreen && windowIsVisible && windowLevelSupported && windowKeyWindow) {
return window;
}
}
return nil;
}
如果你想在任何ViewController中使用它,那么你可以简单地使用。
self.view.window
Berni 的代码很好,但是当应用程序从后台返回时它不起作用。
这是我的代码:
class var safeArea : UIEdgeInsets
{
if #available(iOS 13, *) {
var keyWindow = UIApplication.shared.connectedScenes
.filter({[=10=].activationState == .foregroundActive})
.map({[=10=] as? UIWindowScene})
.compactMap({[=10=]})
.first?.windows
.filter({[=10=].isKeyWindow}).first
// <FIX> the above code doesn't work if the app comes back from background!
if (keyWindow == nil) {
keyWindow = UIApplication.shared.windows.first { [=10=].isKeyWindow }
}
return keyWindow?.safeAreaInsets ?? UIEdgeInsets()
}
else {
guard let keyWindow = UIApplication.shared.keyWindow else { return UIEdgeInsets() }
return keyWindow.safeAreaInsets
}
}
当 .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 { [=10=] as? UIWindowScene }
guard connectedScenes.isEmpty == false else {
fatalError("Connected scenes is empty")
}
let mainWindow = connectedScenes
.flatMap { [=10=].windows }
.first(where: \.isKeyWindow)
guard let window = mainWindow else {
fatalError("Couldn't get main window")
}
return window
}
}
如果您的应用尚未更新为采用基于场景的应用生命周期,另一种获取活动 window 对象的简单方法是通过 UIApplicationDelegate
:
let window = UIApplication.shared.delegate?.window
let rootViewController = window??.rootViewController
我有 answered the question on a duplicate feed,由于我在这里找不到提供尽可能多代码(已注释)的答案,这是我的贡献:
(在 Xcode 13.2.1 上使用 iOS 15.2 运行 测试)
extension UIApplication {
var keyWindow: UIWindow? {
// Get connected scenes
return UIApplication.shared.connectedScenes
// Keep only active scenes, onscreen and visible to the user
.filter { [=10=].activationState == .foregroundActive }
// Keep only the first `UIWindowScene`
.first(where: { [=10=] is UIWindowScene })
// Get its associated windows
.flatMap({ [=10=] as? UIWindowScene })?.windows
// Finally, keep only the key window
.first(where: \.isKeyWindow)
}
}
如果你想在键 UIWindow
中找到出现的 UIViewController
,这里是另一个你可能会发现有用的 extension
:
extension UIApplication {
var keyWindowPresentedController: UIViewController? {
var viewController = self.keyWindow?.rootViewController
// If root `UIViewController` is a `UITabBarController`
if let presentedController = viewController as? UITabBarController {
// Move to selected `UIViewController`
viewController = presentedController.selectedViewController
}
// Go deeper to find the last presented `UIViewController`
while let presentedController = viewController?.presentedViewController {
// If root `UIViewController` is a `UITabBarController`
if let presentedController = presentedController as? UITabBarController {
// Move to selected `UIViewController`
viewController = presentedController.selectedViewController
} else {
// Otherwise, go deeper
viewController = presentedController
}
}
return viewController
}
}
你可以把它放在任何你想要的地方,但我个人将它作为 extension
添加到 UIViewController
。
这让我可以添加更多有用的扩展,例如更容易呈现 UIViewController
的扩展:
extension UIViewController {
func presentInKeyWindow(animated: Bool = true, completion: (() -> Void)? = nil) {
DispatchQueue.main.async {
UIApplication.shared.keyWindow?.rootViewController?
.present(self, animated: animated, completion: completion)
}
}
func presentInKeyWindowPresentedController(animated: Bool = true, completion: (() -> Void)? = nil) {
DispatchQueue.main.async {
UIApplication.shared.keyWindowPresentedController?
.present(self, animated: animated, completion: completion)
}
}
}
如果您使用带有 'first_where' 规则的 SwiftLint 并且想停止交战:
UIApplication.shared.windows.first(where: { [=10=].isKeyWindow })
支持 iOS13 及更高版本。
要继续使用与旧 iOS 版本 UIApplication.shared.keyWindow
相似的语法,请创建此扩展:
extension UIApplication {
var mainKeyWindow: UIWindow? {
get {
if #available(iOS 13, *) {
return connectedScenes
.flatMap { ([=10=] as? UIWindowScene)?.windows ?? [] }
.first { [=10=].isKeyWindow }
} else {
return keyWindow
}
}
}
}
用法
if let keyWindow = UIApplication.shared.mainKeyWindow {
// Do Stuff
}
我已经解决了:
let scenes = UIApplication.shared.connectedScenes
let windowScene = scenes.first as? UIWindowScene
let window = windowScene?.windows.first