16

I want to check if the view controller i am in is root view controller or is pushed on some navigation controller.

Bhumi Goklani
  • 603
  • 1
  • 8
  • 18

4 Answers4

19

[self.navigationController viewControllers];

will return an array of all the viewControllers on the stack. Simply compare the first element in this array to see is the controller the root or not.

e.g.

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

if([vc isEqual: <viewController to check> ])
{
    // code here
}

EDIT: Add Swift

let vc = self.navigationController?.viewControllers.first
if vc == self.navigationController?.visibleViewController {
    //Code Here
}
Jake
  • 2,126
  • 1
  • 10
  • 23
Simon McLoughlin
  • 8,293
  • 5
  • 32
  • 56
  • Note that this answer is correct, answers below are not. When the stack has > 1 element, there is *still* a root view controller living there at the top of that stack! – RobP Dec 09 '14 at 11:50
  • @RobP - I agree that root controller will be living at the 0th index of stack even when stack has >1 element. But as current view controller i.e. topViewController can be root only when it is the only controller in stack. In situation when stack >1 element, topViewController will always be different than the root controller. In this answer _Simon_ is checking if a particular view controller is equal to root controller or not, which is not the question being asked. – Gandalf Dec 09 '14 at 12:09
  • @Gandalf the question asked was, is a given viewController the root or not. Which is what i've answered. There are other ways to do this granted, but this isn't incorrect – Simon McLoughlin Dec 09 '14 at 12:31
  • @SimonMcLoughlin - No, i do not mean it is incorrect, but the question was __"if the view controller i am in is root"__, which means current or topViewController or the last object in navigation stack. For that to be root it has to be firstObject of stack as root will always live at 0th index. I hope you got my point. – Gandalf Dec 09 '14 at 12:54
  • @Gandalf i'm sorry no I don't understand. Your previous comment says that what I have provided is not what the question asked. The user wants to know is the current viewController the root. He can take my code and add `self` into the placeholder in the if check and it will work, because my code will compare the 2 objects and return true if they are the same. The position in the navigation stack is irrelevant to my answer – Simon McLoughlin Dec 09 '14 at 13:00
  • @SimonMcLoughlin - [Can you come to this chat room](http://chat.stackoverflow.com/rooms/info/66483/navigation-controller-stak?tab=general) for further discussion – Gandalf Dec 09 '14 at 13:23
  • 1
    the problem is the definition of "current" -- it should mean "code is currently executing in". not "is currently topmost or visible" – RobP Dec 09 '14 at 15:29
9

Whenever you push any view controller via navigation controller, it manages these view controllers on a stack which is maintained in Last In First Out manner. So if your current view controller is root controller than there can be only one object in the stack. You can check that stack via this code

if([self.navigationController.viewControllers count] == 1)  {  
   //Current view controller is root controller  
}
Gandalf
  • 2,399
  • 2
  • 15
  • 19
4

in your current View controller's viewDidLoad just check self.navigationController.viewControllers.count == 1 mean you are currently in rootview of your navigationstack. make sure you haven't present viewcontroller.

if(self.navigationController.viewControllers.count == 1)
{
    //do what you want
}
ChintaN -Maddy- Ramani
  • 5,156
  • 1
  • 27
  • 48
2

With respect to @Simon answer, I'm adding my answer, to check when you're using some drawer menu, this may help you to find exact root view controller check.

- (BOOL) checkImRoot:(id)controller {
    if(self.window.rootViewController) {
        if(self.window.rootViewController == (UIViewController *)controller) {
            return YES;
        }
    }
    return NO;
}

In example, I'm adding this method in app delegate file, and calling it like this to check,

if([[AppDelegate shareDelegate] checkImRoot:self]) {
     //Yeah, I'm a root vc
}else{
     //Noo, I'm a child vc
}
Hemang
  • 26,840
  • 19
  • 119
  • 186
  • Don't you have an extra `self.window.rootViewController`?! Is that a mistake? – mfaani Jun 29 '17 at 11:40
  • Nope. It's not a mistake. I am simply accessing the `window` property. – Hemang Jun 29 '17 at 11:43
  • I still don't get it. You can just write it using the 2nd line...and if it's not true then just return `nil`. Why have the extra line?! – mfaani Jun 29 '17 at 12:01
  • 1
    @Honey, what is `rootViewController` will be `nil`? Then our comparison might crash our code. – Hemang Jul 02 '17 at 04:16
  • 1
    Hah, you're right. I'm coming from a Swift world where the `rootViewController` is an optional... – mfaani Jul 02 '17 at 04:19