Search code examples
iosswiftviewcontroller

What is the Use of Returning the Same function itself in Swift


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


Solution

  • That is called recursion. There is a condition in the recursion that cause t end the cycle :

    • Not in the navigationController, because it has another visible controller
    • Not in the tabBarController, because it has another visible controller
    • Not presenting another controller, because the presented one is visible

    if one of these appears -> we go down one level and call this function again until none of these true.