在 iOS 13 中获取根视图控制器的正确方法是啥?
Posted
技术标签:
【中文标题】在 iOS 13 中获取根视图控制器的正确方法是啥?【英文标题】:What is the proper way to get root view controller in iOS 13?在 iOS 13 中获取根视图控制器的正确方法是什么? 【发布时间】:2020-05-11 08:40:21 【问题描述】:class TopViewController: UIViewController
override func viewDidLoad()
super.viewDidLoad()
//Code Block 1
let controller = getTopController()
print(controller)// Prints out MyTestProject.TopViewController
//Code Block 2
let controller2 = getRootController()
print(controller2)//Prints out nil , because keywindow is also nil upto this point.
//Code Block 3
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5)
let controller2 = self.getRootController()
print(controller2)// Prints out MyTestProject.TopViewController
func getTopController() -> UIViewController?
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let sceneDelegate = windowScene.delegate as? SceneDelegate else
return nil
return sceneDelegate.window?.rootViewController
func getRootController() -> UIViewController?
let keyWindow = UIApplication.shared.windows.filter $0.isKeyWindow.first
let topController = keyWindow?.rootViewController
return topController
从 ios 13 开始,有两种方法可以获取应用的当前活动/顶视图控制器。 这里: getTopController() 和 getRootController() 显示了这两种方法。
正如在代码中注释的那样,除了 print() 结果是不同的。
在代码块 2 中: getRootController 还找不到窗口,所以它打印出 nil。为什么会这样?
另外,iOS 13 中获取***控制器的完整证明方法,我现在很困惑?
【问题讨论】:
【参考方案1】:根据UIView 的文档,如果视图尚未添加到窗口中,则 window 属性为 nil,即调用 viewDidLoad 时的情况。
尝试在 viewDidAppear 中访问它
override func viewDidAppear(_ animated: Bool)
let controller2 = self.view.window.rootViewController
【讨论】:
【参考方案2】:问题是当你的视图控制器viewDidLoad
window.makeKey()
还没有被调用时。
如果关键窗口不可用,一个可能的解决方法是获取windows
数组中的第一个窗口。
func getRootController() -> UIViewController?
let keyWindow = UIApplication.shared.windows.first(where: $0.isKeyWindow ) ?? UIApplication.shared.windows.first
let topController = keyWindow?.rootViewController
return topController
请注意,这将解决您的问题,但您应该推迟任何涉及使用键窗口的操作,直到它这样做为止。
【讨论】:
但为什么 getTopController() 方法的情况不同?即使在 viewDidLoad 中调用 Window 也不在那里。 问题不在于窗口为nil,窗口存在但isKeyWindow
为假,因为window.makeKey()
还没有被调用。以上是关于在 iOS 13 中获取根视图控制器的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章