iOS 获取当前的controller
作为一名经验丰富的开发者,你肩负着教导一位刚入行的小白如何获取当前的controller的任务。下面我将为你详细介绍这个过程,并提供相应的代码示例。
整体流程
获取当前的controller实际上是获取当前屏幕上显示的视图控制器(UIViewController)。这个过程可以分为以下几个步骤:
- 获取应用的根视图控制器(Root View Controller)
- 从根视图控制器开始,递归地找到当前显示的视图控制器
下面的表格展示了整个流程的步骤:
步骤 | 描述 |
---|---|
1 | 获取应用的根视图控制器 |
2 | 从根视图控制器开始递归查找当前显示的视图控制器 |
接下来,我们将详细介绍每个步骤需要做的事情以及相应的代码。
步骤1:获取应用的根视图控制器
首先,我们需要获取应用的根视图控制器。应用的根视图控制器是应用启动后的第一个显示在屏幕上的视图控制器。我们可以通过UIApplication
的shared
实例的keyWindow
属性来获取应用的主窗口(UIWindow),然后从主窗口中获取根视图控制器。下面是获取根视图控制器的代码示例:
guard let keyWindow = UIApplication.shared.keyWindow else {
return nil
}
let rootViewController = keyWindow.rootViewController
注释:
keyWindow
:应用的主窗口rootViewController
:应用的根视图控制器
步骤2:递归查找当前显示的视图控制器
获取了应用的根视图控制器后,我们需要从根视图控制器开始递归地查找当前显示的视图控制器。递归查找的原理是在每个视图控制器中判断其是否是当前显示的视图控制器,如果是则返回,否则继续递归查找其子视图控制器。下面是递归查找的代码示例:
func getCurrentViewController(rootViewController: UIViewController?) -> UIViewController? {
guard let rootViewController = rootViewController else {
return nil
}
if let presentedViewController = rootViewController.presentedViewController {
// 如果当前视图控制器有presentedViewController,说明有弹出的视图控制器
return getCurrentViewController(rootViewController: presentedViewController)
}
if let navigationController = rootViewController as? UINavigationController {
// 如果当前视图控制器是导航控制器,获取导航控制器的栈顶视图控制器
return getCurrentViewController(rootViewController: navigationController.visibleViewController)
}
if let tabBarController = rootViewController as? UITabBarController {
// 如果当前视图控制器是标签栏控制器,获取当前选中的视图控制器
return getCurrentViewController(rootViewController: tabBarController.selectedViewController)
}
// 其他情况,直接返回当前视图控制器
return rootViewController
}
let currentViewController = getCurrentViewController(rootViewController: rootViewController)
注释:
getCurrentViewController
:递归查找当前显示的视图控制器的方法presentedViewController
:当前视图控制器弹出的视图控制器visibleViewController
:导航控制器的栈顶视图控制器selectedViewController
:标签栏控制器当前选中的视图控制器currentViewController
:当前显示的视图控制器
关系图
下面是一个关系图,展示了获取当前的controller的过程:
erDiagram
ROOT_VIEW_CONTROLLER ||..|> CURRENT_VIEW_CONTROLLER : contains
CURRENT_VIEW_CONTROLLER ||--|> PRESENTED_VIEW_CONTROLLER : has presented
ROOT_VIEW_CONTROLLER ||--|> NAVIGATION_CONTROLLER : is navigation controller
ROOT_VIEW_CONTROLLER ||--|> TAB_BAR_CONTROLLER : is tab bar controller