Well I see some syntax in the following function which returns the topMostViewController. This function is defined in AppDelegate
func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
if let navigationController = controller as? UINavigationController {
//***A topViewController which is Returning itself
//***This is where I got Confusion
return topViewController(controller: navigationController.visibleViewController)
} else if let tabController = controller as? UITabBarController {
if let selected = tabController.selectedViewController {
return topViewController(controller: selected)
}
} else if let presented = controller?.presentedViewController {
return topViewController(controller: presented)
}
return controller
}
And it's used as
if (self.topViewController() as? SomeViewController) != nil {
if orientation.isPortrait {
return .portrait
} else {
return .landscape
}
}
I understood that the code is trying to set orientation based on the currently visible View Controller but I don't understand what is the necessity of returning the same function itself in topViewController
. Also I see some syntax like
extension UIApplication {
/// The top most view controller
static var topMostViewController: UIViewController? {
return UIApplication.shared.keyWindow?.rootViewController?.visibleViewController
}
}
extension UIViewController {
/// The visible view controller from a given view controller
var visibleViewController: UIViewController? {
if let navigationController = self as? UINavigationController {
// *** Here it's returning Same variable i.e visibleViewController
// *** a function could call itself recursively. But how can a Variable calls itself recursively?
return navigationController.topViewController?.visibleViewController
} else if let tabBarController = self as? UITabBarController {
return tabBarController.selectedViewController?.visibleViewController
} else if let presentedViewController = presentedViewController {
return presentedViewController.visibleViewController
} else {
return self
}
}
}
Edited
That is called recursion. There is a condition in the recursion that cause t end the cycle :
navigationController
, because it has another visible controllertabBarController
, because it has another visible controllerif one of these appears -> we go down one level and call this function again until none of these true.