How do I get the RootViewController from a pushed controller?

前端 未结 9 1427
小鲜肉
小鲜肉 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 07:54

    A slightly less ugly version of the same thing mentioned in pretty much all these answers:

    UIViewController *rootViewController = [[self.navigationController viewControllers] firstObject];
    

    in your case, I'd probably do something like:

    inside your UINavigationController subclass:

    - (UIViewController *)rootViewController
    {
        return [[self viewControllers] firstObject];
    }
    

    then you can use:

    UIViewController *rootViewController = [self.navigationController rootViewController];
    

    edit

    OP asked for a property in the comments.

    if you like, you can access this via something like self.navigationController.rootViewController by just adding a readonly property to your header:

    @property (nonatomic, readonly, weak) UIViewController *rootViewController;
    
    0 讨论(0)
  • 2020-12-04 07:58

    How about asking the UIApplication singleton for its keyWindow, and from that UIWindow ask for the root view controller (its rootViewController property):

    UIViewController root = [[[UIApplication sharedApplication] keyWindow] rootViewController];
    
    0 讨论(0)
  • 2020-12-04 08:05

    Here I came up with universal method to navigate from any place to root.

    1. You create a new Class file with this class, so that it's accessible from anywhere in your project:

      import UIKit
      
      class SharedControllers
      {
          static func navigateToRoot(viewController: UIViewController)
          {
              var nc = viewController.navigationController
      
              // If this is a normal view with NavigationController, then we just pop to root.
              if nc != nil
              {
                  nc?.popToRootViewControllerAnimated(true)
                  return
              }
      
              // Most likely we are in Modal view, so we will need to search for a view with NavigationController.
              let vc = viewController.presentingViewController
      
              if nc == nil
              {
                  nc = viewController.presentingViewController?.navigationController
              }
      
              if nc == nil
              {
                  nc = viewController.parentViewController?.navigationController
              }
      
              if vc is UINavigationController && nc == nil
              {
                  nc = vc as? UINavigationController
              }
      
              if nc != nil
              {
                  viewController.dismissViewControllerAnimated(false, completion:
                      {
                          nc?.popToRootViewControllerAnimated(true)
                  })
              }
          }
      }
      
    2. Usage from anywhere in your project:

      {
          ...
          SharedControllers.navigateToRoot(self)
          ...
      }
      
    0 讨论(0)
  • 2020-12-04 08:07

    Swift version :

    var rootViewController = self.navigationController?.viewControllers.first
    

    ObjectiveC version :

    UIViewController *rootViewController = [self.navigationController.viewControllers firstObject];
    

    Where self is an instance of a UIViewController embedded in a UINavigationController.

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

    As an addition to @dulgan's answer, it is always a good approach to use firstObject over objectAtIndex:0, because while first one returns nil if there is no object in the array, latter one throws exception.

    UIViewController *rootViewController = self.navigationController.rootViewController;
    

    Alternatively, it'd be a big plus for you to create a category named UINavigationController+Additions and define your method in that.

    @interface UINavigationController (Additions)
    
    - (UIViewController *)rootViewController;
    
    @end
    
    @implementation UINavigationController (Additions)
    
    - (UIViewController *)rootViewController
    {
        return self.viewControllers.firstObject;
    }
    
    @end
    
    0 讨论(0)
  • 2020-12-04 08:11

    Use the viewControllers property of the UINavigationController. Example code:

    // Inside another ViewController
    NSArray *viewControllers = self.navigationController.viewControllers;
    UIViewController *rootViewController = [viewControllers objectAtIndex:viewControllers.count - 2];
    

    This is the standard way of getting the "back" view controller. The reason objectAtIndex:0 works is because the view controller you're trying to access is also the root one, if you were deeper in the navigation, the back view would not be the same as the root view.

    0 讨论(0)
提交回复
热议问题