How do I get the RootViewController from a pushed controller?












131















So, I push a view controller from RootViewController like:




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


BUT, FROM anotherViewController now, I want to access the RootViewController again.



I'm trying




// (inside anotherViewController now)
///RootViewController *root = (RootViewController*)self.parentViewController ; // No.
// err
RootViewController *root = (RootViewController*)[self.navigationController.viewControllers objectAtIndex:0] ; // YES!! it works



I'm not sure WHY this works and I'm not sure if its the best way to do it. Can somebody comment on a better way to get the RootViewController from a controller you've pushed into that RootViewController's navigationController and whether or not the way I've done it is reliable or not?










share|improve this question























  • What you've done will reliably get the root view controller (the first one in the navigation hierarchy), if you want to get access to the "back" view controller, see my answer.

    – Ben S
    Nov 24 '09 at 21:13











  • See also "What does setting the UIWindow's rootViewController do?"

    – bobobobo
    Mar 23 '13 at 19:37
















131















So, I push a view controller from RootViewController like:




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


BUT, FROM anotherViewController now, I want to access the RootViewController again.



I'm trying




// (inside anotherViewController now)
///RootViewController *root = (RootViewController*)self.parentViewController ; // No.
// err
RootViewController *root = (RootViewController*)[self.navigationController.viewControllers objectAtIndex:0] ; // YES!! it works



I'm not sure WHY this works and I'm not sure if its the best way to do it. Can somebody comment on a better way to get the RootViewController from a controller you've pushed into that RootViewController's navigationController and whether or not the way I've done it is reliable or not?










share|improve this question























  • What you've done will reliably get the root view controller (the first one in the navigation hierarchy), if you want to get access to the "back" view controller, see my answer.

    – Ben S
    Nov 24 '09 at 21:13











  • See also "What does setting the UIWindow's rootViewController do?"

    – bobobobo
    Mar 23 '13 at 19:37














131












131








131


28






So, I push a view controller from RootViewController like:




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


BUT, FROM anotherViewController now, I want to access the RootViewController again.



I'm trying




// (inside anotherViewController now)
///RootViewController *root = (RootViewController*)self.parentViewController ; // No.
// err
RootViewController *root = (RootViewController*)[self.navigationController.viewControllers objectAtIndex:0] ; // YES!! it works



I'm not sure WHY this works and I'm not sure if its the best way to do it. Can somebody comment on a better way to get the RootViewController from a controller you've pushed into that RootViewController's navigationController and whether or not the way I've done it is reliable or not?










share|improve this question














So, I push a view controller from RootViewController like:




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


BUT, FROM anotherViewController now, I want to access the RootViewController again.



I'm trying




// (inside anotherViewController now)
///RootViewController *root = (RootViewController*)self.parentViewController ; // No.
// err
RootViewController *root = (RootViewController*)[self.navigationController.viewControllers objectAtIndex:0] ; // YES!! it works



I'm not sure WHY this works and I'm not sure if its the best way to do it. Can somebody comment on a better way to get the RootViewController from a controller you've pushed into that RootViewController's navigationController and whether or not the way I've done it is reliable or not?







iphone uinavigationcontroller






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 24 '09 at 20:54









bobobobobobobobo

35.5k44214303




35.5k44214303













  • What you've done will reliably get the root view controller (the first one in the navigation hierarchy), if you want to get access to the "back" view controller, see my answer.

    – Ben S
    Nov 24 '09 at 21:13











  • See also "What does setting the UIWindow's rootViewController do?"

    – bobobobo
    Mar 23 '13 at 19:37



















  • What you've done will reliably get the root view controller (the first one in the navigation hierarchy), if you want to get access to the "back" view controller, see my answer.

    – Ben S
    Nov 24 '09 at 21:13











  • See also "What does setting the UIWindow's rootViewController do?"

    – bobobobo
    Mar 23 '13 at 19:37

















What you've done will reliably get the root view controller (the first one in the navigation hierarchy), if you want to get access to the "back" view controller, see my answer.

– Ben S
Nov 24 '09 at 21:13





What you've done will reliably get the root view controller (the first one in the navigation hierarchy), if you want to get access to the "back" view controller, see my answer.

– Ben S
Nov 24 '09 at 21:13













See also "What does setting the UIWindow's rootViewController do?"

– bobobobo
Mar 23 '13 at 19:37





See also "What does setting the UIWindow's rootViewController do?"

– bobobobo
Mar 23 '13 at 19:37












7 Answers
7






active

oldest

votes


















130














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.






share|improve this answer





















  • 5





    :) ty. It still seems hacky - :) I really wanted an "official" member to do the job, something like self.navigationController.rootViewController, but alas, no such thing..

    – bobobobo
    Nov 25 '09 at 2:21






  • 61





    The code above is erroneous. rootViewController is missing * before it, and the index should just be 0. The code in the question is correct: RootViewController *root = (RootViewController *)[navigationController.viewControllers objectAtIndex:0]

    – ma11hew28
    Apr 29 '11 at 17:23








  • 1





    Agreed: the above code returns the parent view controller, not the root view controller as the OP asked. Still, that's what Ben S said he'll do, he just didn't point that out enough.

    – Ivan Vučica
    Dec 6 '11 at 12:17













  • The 2nd line should read: UIViewController *rootViewController = [viewControllers objectAtIndex:viewControllers.count - 1];

    – Billy
    May 19 '16 at 19:44





















161














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.






share|improve this answer


























  • Can I get navigationController of another ViewController from a different class?

    – sasquatch
    Oct 15 '15 at 7:57











  • Any UIViewController subclass will have a navigationController property, which points to it's first parentViewController matching UINavigationController class.

    – dulgan
    Oct 15 '15 at 8:07











  • Did the trick and simplest answer :) Thank you

    – MBH
    Oct 3 '17 at 10:12



















12














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;





share|improve this answer

































    7














    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 as? UIViewController
    }
    }





    share|improve this answer
























    • Thanks! Also you can remove "as? UIViewController"

      – atereshkov
      Jul 12 '18 at 11:12



















    3














    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





    share|improve this answer


























    • I just added this part without reading your answer, you're totally right with the "firstObject" being better thant [0]

      – dulgan
      Feb 10 '15 at 13:49



















    1














    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];





    share|improve this answer


























    • how to get navigation controller ?

      – Yestay Muratov
      Dec 2 '16 at 17:44











    • This is a wrong suggestion as what if my rootviewcontroller of application is UITabBarViewController?

      – Sandeep Singh Rana
      Aug 31 '18 at 10:08



















    1














    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)
      ...
      }







    share|improve this answer

























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f1792858%2fhow-do-i-get-the-rootviewcontroller-from-a-pushed-controller%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      7 Answers
      7






      active

      oldest

      votes








      7 Answers
      7






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      130














      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.






      share|improve this answer





















      • 5





        :) ty. It still seems hacky - :) I really wanted an "official" member to do the job, something like self.navigationController.rootViewController, but alas, no such thing..

        – bobobobo
        Nov 25 '09 at 2:21






      • 61





        The code above is erroneous. rootViewController is missing * before it, and the index should just be 0. The code in the question is correct: RootViewController *root = (RootViewController *)[navigationController.viewControllers objectAtIndex:0]

        – ma11hew28
        Apr 29 '11 at 17:23








      • 1





        Agreed: the above code returns the parent view controller, not the root view controller as the OP asked. Still, that's what Ben S said he'll do, he just didn't point that out enough.

        – Ivan Vučica
        Dec 6 '11 at 12:17













      • The 2nd line should read: UIViewController *rootViewController = [viewControllers objectAtIndex:viewControllers.count - 1];

        – Billy
        May 19 '16 at 19:44


















      130














      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.






      share|improve this answer





















      • 5





        :) ty. It still seems hacky - :) I really wanted an "official" member to do the job, something like self.navigationController.rootViewController, but alas, no such thing..

        – bobobobo
        Nov 25 '09 at 2:21






      • 61





        The code above is erroneous. rootViewController is missing * before it, and the index should just be 0. The code in the question is correct: RootViewController *root = (RootViewController *)[navigationController.viewControllers objectAtIndex:0]

        – ma11hew28
        Apr 29 '11 at 17:23








      • 1





        Agreed: the above code returns the parent view controller, not the root view controller as the OP asked. Still, that's what Ben S said he'll do, he just didn't point that out enough.

        – Ivan Vučica
        Dec 6 '11 at 12:17













      • The 2nd line should read: UIViewController *rootViewController = [viewControllers objectAtIndex:viewControllers.count - 1];

        – Billy
        May 19 '16 at 19:44
















      130












      130








      130







      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.






      share|improve this answer















      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.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited May 15 '16 at 23:55









      Chris Nolet

      5,34854684




      5,34854684










      answered Nov 24 '09 at 21:10









      Ben SBen S

      57.2k24155205




      57.2k24155205








      • 5





        :) ty. It still seems hacky - :) I really wanted an "official" member to do the job, something like self.navigationController.rootViewController, but alas, no such thing..

        – bobobobo
        Nov 25 '09 at 2:21






      • 61





        The code above is erroneous. rootViewController is missing * before it, and the index should just be 0. The code in the question is correct: RootViewController *root = (RootViewController *)[navigationController.viewControllers objectAtIndex:0]

        – ma11hew28
        Apr 29 '11 at 17:23








      • 1





        Agreed: the above code returns the parent view controller, not the root view controller as the OP asked. Still, that's what Ben S said he'll do, he just didn't point that out enough.

        – Ivan Vučica
        Dec 6 '11 at 12:17













      • The 2nd line should read: UIViewController *rootViewController = [viewControllers objectAtIndex:viewControllers.count - 1];

        – Billy
        May 19 '16 at 19:44
















      • 5





        :) ty. It still seems hacky - :) I really wanted an "official" member to do the job, something like self.navigationController.rootViewController, but alas, no such thing..

        – bobobobo
        Nov 25 '09 at 2:21






      • 61





        The code above is erroneous. rootViewController is missing * before it, and the index should just be 0. The code in the question is correct: RootViewController *root = (RootViewController *)[navigationController.viewControllers objectAtIndex:0]

        – ma11hew28
        Apr 29 '11 at 17:23








      • 1





        Agreed: the above code returns the parent view controller, not the root view controller as the OP asked. Still, that's what Ben S said he'll do, he just didn't point that out enough.

        – Ivan Vučica
        Dec 6 '11 at 12:17













      • The 2nd line should read: UIViewController *rootViewController = [viewControllers objectAtIndex:viewControllers.count - 1];

        – Billy
        May 19 '16 at 19:44










      5




      5





      :) ty. It still seems hacky - :) I really wanted an "official" member to do the job, something like self.navigationController.rootViewController, but alas, no such thing..

      – bobobobo
      Nov 25 '09 at 2:21





      :) ty. It still seems hacky - :) I really wanted an "official" member to do the job, something like self.navigationController.rootViewController, but alas, no such thing..

      – bobobobo
      Nov 25 '09 at 2:21




      61




      61





      The code above is erroneous. rootViewController is missing * before it, and the index should just be 0. The code in the question is correct: RootViewController *root = (RootViewController *)[navigationController.viewControllers objectAtIndex:0]

      – ma11hew28
      Apr 29 '11 at 17:23







      The code above is erroneous. rootViewController is missing * before it, and the index should just be 0. The code in the question is correct: RootViewController *root = (RootViewController *)[navigationController.viewControllers objectAtIndex:0]

      – ma11hew28
      Apr 29 '11 at 17:23






      1




      1





      Agreed: the above code returns the parent view controller, not the root view controller as the OP asked. Still, that's what Ben S said he'll do, he just didn't point that out enough.

      – Ivan Vučica
      Dec 6 '11 at 12:17







      Agreed: the above code returns the parent view controller, not the root view controller as the OP asked. Still, that's what Ben S said he'll do, he just didn't point that out enough.

      – Ivan Vučica
      Dec 6 '11 at 12:17















      The 2nd line should read: UIViewController *rootViewController = [viewControllers objectAtIndex:viewControllers.count - 1];

      – Billy
      May 19 '16 at 19:44







      The 2nd line should read: UIViewController *rootViewController = [viewControllers objectAtIndex:viewControllers.count - 1];

      – Billy
      May 19 '16 at 19:44















      161














      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.






      share|improve this answer


























      • Can I get navigationController of another ViewController from a different class?

        – sasquatch
        Oct 15 '15 at 7:57











      • Any UIViewController subclass will have a navigationController property, which points to it's first parentViewController matching UINavigationController class.

        – dulgan
        Oct 15 '15 at 8:07











      • Did the trick and simplest answer :) Thank you

        – MBH
        Oct 3 '17 at 10:12
















      161














      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.






      share|improve this answer


























      • Can I get navigationController of another ViewController from a different class?

        – sasquatch
        Oct 15 '15 at 7:57











      • Any UIViewController subclass will have a navigationController property, which points to it's first parentViewController matching UINavigationController class.

        – dulgan
        Oct 15 '15 at 8:07











      • Did the trick and simplest answer :) Thank you

        – MBH
        Oct 3 '17 at 10:12














      161












      161








      161







      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.






      share|improve this answer















      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.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jun 9 '17 at 7:59

























      answered May 2 '13 at 14:04









      dulgandulgan

      5,92433244




      5,92433244













      • Can I get navigationController of another ViewController from a different class?

        – sasquatch
        Oct 15 '15 at 7:57











      • Any UIViewController subclass will have a navigationController property, which points to it's first parentViewController matching UINavigationController class.

        – dulgan
        Oct 15 '15 at 8:07











      • Did the trick and simplest answer :) Thank you

        – MBH
        Oct 3 '17 at 10:12



















      • Can I get navigationController of another ViewController from a different class?

        – sasquatch
        Oct 15 '15 at 7:57











      • Any UIViewController subclass will have a navigationController property, which points to it's first parentViewController matching UINavigationController class.

        – dulgan
        Oct 15 '15 at 8:07











      • Did the trick and simplest answer :) Thank you

        – MBH
        Oct 3 '17 at 10:12

















      Can I get navigationController of another ViewController from a different class?

      – sasquatch
      Oct 15 '15 at 7:57





      Can I get navigationController of another ViewController from a different class?

      – sasquatch
      Oct 15 '15 at 7:57













      Any UIViewController subclass will have a navigationController property, which points to it's first parentViewController matching UINavigationController class.

      – dulgan
      Oct 15 '15 at 8:07





      Any UIViewController subclass will have a navigationController property, which points to it's first parentViewController matching UINavigationController class.

      – dulgan
      Oct 15 '15 at 8:07













      Did the trick and simplest answer :) Thank you

      – MBH
      Oct 3 '17 at 10:12





      Did the trick and simplest answer :) Thank you

      – MBH
      Oct 3 '17 at 10:12











      12














      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;





      share|improve this answer






























        12














        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;





        share|improve this answer




























          12












          12








          12







          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;





          share|improve this answer















          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;






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Oct 7 '16 at 21:14









          Stunner

          7,9191069124




          7,9191069124










          answered Dec 16 '13 at 0:15









          JesseJesse

          6,09695076




          6,09695076























              7














              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 as? UIViewController
              }
              }





              share|improve this answer
























              • Thanks! Also you can remove "as? UIViewController"

                – atereshkov
                Jul 12 '18 at 11:12
















              7














              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 as? UIViewController
              }
              }





              share|improve this answer
























              • Thanks! Also you can remove "as? UIViewController"

                – atereshkov
                Jul 12 '18 at 11:12














              7












              7








              7







              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 as? UIViewController
              }
              }





              share|improve this answer













              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 as? UIViewController
              }
              }






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Jul 10 '15 at 14:56









              cschcsch

              1,1751112




              1,1751112













              • Thanks! Also you can remove "as? UIViewController"

                – atereshkov
                Jul 12 '18 at 11:12



















              • Thanks! Also you can remove "as? UIViewController"

                – atereshkov
                Jul 12 '18 at 11:12

















              Thanks! Also you can remove "as? UIViewController"

              – atereshkov
              Jul 12 '18 at 11:12





              Thanks! Also you can remove "as? UIViewController"

              – atereshkov
              Jul 12 '18 at 11:12











              3














              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





              share|improve this answer


























              • I just added this part without reading your answer, you're totally right with the "firstObject" being better thant [0]

                – dulgan
                Feb 10 '15 at 13:49
















              3














              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





              share|improve this answer


























              • I just added this part without reading your answer, you're totally right with the "firstObject" being better thant [0]

                – dulgan
                Feb 10 '15 at 13:49














              3












              3








              3







              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





              share|improve this answer















              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






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Nov 14 '18 at 19:50

























              answered Jan 24 '15 at 1:30









              ozgurozgur

              28k145383




              28k145383













              • I just added this part without reading your answer, you're totally right with the "firstObject" being better thant [0]

                – dulgan
                Feb 10 '15 at 13:49



















              • I just added this part without reading your answer, you're totally right with the "firstObject" being better thant [0]

                – dulgan
                Feb 10 '15 at 13:49

















              I just added this part without reading your answer, you're totally right with the "firstObject" being better thant [0]

              – dulgan
              Feb 10 '15 at 13:49





              I just added this part without reading your answer, you're totally right with the "firstObject" being better thant [0]

              – dulgan
              Feb 10 '15 at 13:49











              1














              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];





              share|improve this answer


























              • how to get navigation controller ?

                – Yestay Muratov
                Dec 2 '16 at 17:44











              • This is a wrong suggestion as what if my rootviewcontroller of application is UITabBarViewController?

                – Sandeep Singh Rana
                Aug 31 '18 at 10:08
















              1














              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];





              share|improve this answer


























              • how to get navigation controller ?

                – Yestay Muratov
                Dec 2 '16 at 17:44











              • This is a wrong suggestion as what if my rootviewcontroller of application is UITabBarViewController?

                – Sandeep Singh Rana
                Aug 31 '18 at 10:08














              1












              1








              1







              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];





              share|improve this answer















              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];






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Aug 26 '13 at 0:52

























              answered Aug 26 '13 at 0:43









              Basil BourqueBasil Bourque

              112k28385545




              112k28385545













              • how to get navigation controller ?

                – Yestay Muratov
                Dec 2 '16 at 17:44











              • This is a wrong suggestion as what if my rootviewcontroller of application is UITabBarViewController?

                – Sandeep Singh Rana
                Aug 31 '18 at 10:08



















              • how to get navigation controller ?

                – Yestay Muratov
                Dec 2 '16 at 17:44











              • This is a wrong suggestion as what if my rootviewcontroller of application is UITabBarViewController?

                – Sandeep Singh Rana
                Aug 31 '18 at 10:08

















              how to get navigation controller ?

              – Yestay Muratov
              Dec 2 '16 at 17:44





              how to get navigation controller ?

              – Yestay Muratov
              Dec 2 '16 at 17:44













              This is a wrong suggestion as what if my rootviewcontroller of application is UITabBarViewController?

              – Sandeep Singh Rana
              Aug 31 '18 at 10:08





              This is a wrong suggestion as what if my rootviewcontroller of application is UITabBarViewController?

              – Sandeep Singh Rana
              Aug 31 '18 at 10:08











              1














              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)
                ...
                }







              share|improve this answer






























                1














                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)
                  ...
                  }







                share|improve this answer




























                  1












                  1








                  1







                  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)
                    ...
                    }







                  share|improve this answer















                  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)
                    ...
                    }








                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Mar 5 '16 at 19:42

























                  answered Mar 5 '16 at 11:51









                  MarisMaris

                  3441212




                  3441212






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f1792858%2fhow-do-i-get-the-rootviewcontroller-from-a-pushed-controller%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Florida Star v. B. J. F.

                      Error while running script in elastic search , gateway timeout

                      Adding quotations to stringified JSON object values