How to check if navigation controller is pushed or is a root view controller?
Asked Answered
A

4

17

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

Administration answered 9/12, 2014 at 11:38 Comment(2)
check self.navigationController.viewControllers it will give you array of your pushed navigation viewcontrollersTranscendent
You can use self.navigationController.topViewController == self to check if it is the rootViewControllerCustombuilt
N
20

[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
}
Nautilus answered 9/12, 2014 at 11:41 Comment(7)
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!Protectionist
@Protectionist - 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.Hyades
@Hyades 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 incorrectNautilus
@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.Hyades
@Hyades 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 answerNautilus
@SimonMcLoughlin - Can you come to this chat room for further discussionHyades
the problem is the definition of "current" -- it should mean "code is currently executing in". not "is currently topmost or visible"Protectionist
H
10

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  
}
Hyades answered 9/12, 2014 at 11:47 Comment(0)
T
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
}
Transcendent answered 9/12, 2014 at 11:47 Comment(0)
T
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
}
Triptolemus answered 9/12, 2014 at 11:53 Comment(5)
Don't you have an extra self.window.rootViewController?! Is that a mistake?Slay
Nope. It's not a mistake. I am simply accessing the window property.Triptolemus
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?!Slay
@Honey, what is rootViewController will be nil? Then our comparison might crash our code.Triptolemus
Hah, you're right. I'm coming from a Swift world where the rootViewController is an optional...Slay

© 2022 - 2024 — McMap. All rights reserved.