在Swift应用程序中如何获取keyWindow引用?

36

在Objective-C中,我在UIViewController的viewDidLoad方法中执行以下代码来获取我的iOS应用程序中keyWindow的引用:

 UIWindow * keyWindow = [[UIApplication sharedApplication] keyWindow];

因此,我正在将此视图控制器移植到Swift,并在viewDidLoad调用中执行以下操作:

let window = UIApplication.sharedApplication().keyWindow

我试图理解为什么窗口是nil。当我在那一行后面设置断点,然后在控制台中检查窗口时,我得到了这个:

(lldb) po window
nil

我该如何在Swift中将“window”设置为应用程序的keyWindow的有效引用?


1
也许 let window: UIWindow? = UIApplication.sharedApplication().windows[0] as? UIWindow 可以提供你所需的内容... 或者自从 func viewDidAppear(_ animated: Bool)(直到你的视图可见!)你可以通过 self.view.window 直接访问窗口,也许那才是你要找的... - holex
7个回答

42

在我寻找如何在Swift中获取窗口时,我遇到了这个问题。如果你想获取窗口而不是keyWindow,请尝试以下方法(Swift 2):

我在搜索获取Swift窗口的过程中遇到了这个问题。如果你想要获取窗口而不是keyWindow,请尝试以下代码(Swift 2):

if let app = UIApplication.sharedApplication().delegate as? AppDelegate, let window = app.window {
    MBProgressHUD.show(text, view:window)
}

更新至Swift 3:(感谢 @Trevor)

if let app = UIApplication.shared.delegate as? AppDelegate, let window = app.window {
    MBProgressHUD.show(text, view:window)
}

谢谢,:) 这节省了我的时间。 - Gautam Sareriya
但是window.keyWindow会是false吗?!let windowFirst = NSApp.windows.first print(windowFirst!.keyWindow) - allenlinli
@allenlinli 我认为讨论是关于iOS,不确定是否涉及到macOS - superarts.org
如果我在pod文件中使用此代码,但它找不到AppDelegate文件,我该怎么办? - Yestay Muratov
@YestayMuratov 我不确定我是否理解了,但我会尝试。一般来说,您仍然可以从共享组件中获取UIApplication.shared.delegate,但您将无法知道类AppDelegate。您可以做的一件事是创建一个MyPodAppDelegateProtocol,并在您的pod中使用该接口,在主应用程序中,当然AppDelegate必须确认此协议。但是最好您单独提出这个问题,因为上述方法听起来不像是一个好的设计,因为它违反了多个软件工程师原则,特别是依赖性原则。 - superarts.org

27

在Swift 4中,只需使用UIApplication.shared.keyWindow属性,无需强制转换即可获得。

请注意,iOS 13/iPadOS引入了UIScenes和对多窗口的明确支持,因此不再支持keyWindow概念,因为它不再有效。

这个问题概述了如何访问基于场景的窗口。


4
keyWindow 在 iOS 13 中已经被弃用。 https://developer.apple.com/documentation/uikit/uiapplication/1622924-keywindow - Xavier L.

17

Swift 5.1

可以正常工作

如果您还在寻找处理foregroundbackground模式的方法,您应该尝试这个

UIApplication.shared.windows.first(where: { $0.isKeyWindow })

救命稻草。谢谢。 - Alex Zavatone

4

更新superarts.org对Swift 3的答案:

if let app = UIApplication.shared.delegate as? AppDelegate, let window = app.window { 
      MBProgressHUD.show(text, view: window)
}

4
最简单的方法是:
使用Objective-C。
[UIApplication sharedApplication].windows.firstObject

在Swift中

UIApplication.shared.windows.first!

请注意,仅在您不支持多个窗口时才有效。

Cocoa中已经有多个窗口了。状态窗口、文本输入窗口和主窗口。 - Alex Zavatone

3

在viewDidLoad方法中,关键窗口还没有被设置好。你的代码在viewDidAppear中可以正常工作。或者你可以在viewDidLoad中获取windows数组,并从该数组中获取一个(如果有多个)窗口。


2

不要在didLoad函数中调用window,而应该在ViewController的viewDidAppear函数中调用keyWindow。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接