How do I get the RootViewController from a pushed controller?

前端 未结 9 1428
小鲜肉
小鲜肉 2020-12-04 07:50

So, I push a view controller from RootViewController like:

[self.navigationController pushViewController:anotherViewController animated:YES] ;

BUT, FRO

相关标签:
9条回答
  • 2020-12-04 08:12

    This worked for me:

    When my root view controller is embedded in a navigation controller:

    UINavigationController * navigationController = (UINavigationController *)[[[[UIApplication sharedApplication] windows] firstObject] rootViewController];
    RootViewController * rootVC = (RootViewController *)[[navigationController viewControllers] firstObject];
    

    Remember that keyWindow is deprecated.

    0 讨论(0)
  • 2020-12-04 08:13

    For all who are interested in a swift extension, this is what I'm using now:

    extension UINavigationController {
        var rootViewController : UIViewController? {
            return self.viewControllers.first
        }
    }
    
    0 讨论(0)
  • I encounter a strange condition.

    self.viewControllers.first is not root viewController always.

    Generally, self.viewControllers.first is root viewController indeed. But sometimes it's not.

    class MyCustomMainNavigationController: UINavigationController {
    
        function configureForView(_ v: UIViewController, animated: Bool) {
            let root = self.viewControllers.first
            let isRoot = (v == root)
        
            // Update UI based on isRoot
            // ....
        }
    }
    
    extension MyCustomMainNavigationController: UINavigationControllerDelegate {
        func navigationController(_ navigationController: UINavigationController, 
            willShow viewController: UIViewController, 
            animated: Bool) {
    
            self.configureForView(viewController, animated: animated)
        }
    }
    

    My issue:

    Generally, self.viewControllers.first is root viewController. But, when I call popToRootViewController(animated:), and then it triggers navigationController(_:willShow:animated:). At this moment, self.viewControllers.first is NOT root viewController, it's the last viewController which will disappear.

    Summary

    • self.viewControllers.first is not always root viewController. Sometime, it will be the last viewController.

    So, I suggest to keep rootViewController by property when self.viewControllers have ONLY one viewController. I get root viewController in viewDidLoad() of custom UINavigationController.

    class MyCustomMainNavigationController: UINavigationController {
        fileprivate var myRoot: UIViewController!
        override func viewDidLoad() {
    
            super.viewDidLoad()
    
            // My UINavigationController is defined in storyboard. 
            // So at this moment, 
            // I can get root viewController by `self.topViewController!`
            let v = self.topViewController!
            self.myRoot = v
        }
    
    }
    

    Enviroments:

    • iPhone 7 with iOS 14.0.1
    • Xcode 12.0.1 (12A7300)
    0 讨论(0)
提交回复
热议问题