'iOS check if Back Button is displayed in UINavigationController

In iOS project I need to check if the back button is currently displayed. I've tried some solutions provided on SO, but none of them worked for me. Currently I'm working with this code

NSArray *stack = navigationController.viewControllers;
int i = stack.count-2;

if (i>=0)
{
    UIViewController *backVC = (UIViewController*)[stack objectAtIndex:i];
    if (backVC.navigationItem.backBarButtonItem != nil) {
        NSLog(@"Back button is displayed!");
    }
}

But nothing appears in log. If I understood apple guides correctly, I'm looking for ViewController that sits int the stack at index n-2, that ViewController is supposed to hold a back button.

I'm using this code inside -navigationController:willShowViewController:animated:



Solution 1:[1]

This is more reliable and probably the right way to do it

Swift :

guard let navigationStack = navigationController?.viewControllers, navigationStack.count > 1 else {
    // The back button is not present
    return
}
// The back button is present

Solution 2:[2]

I had the same issue today and after trying variations on the above code, I have settled on detecting whether a back button should be displayed using:

 self.navigationController.navigationBar.backItem

From the docs:

If the leftBarButtonItem property of the topmost navigation item is nil, the navigation bar displays a back button whose title is derived from the item in this property. If there is only one item on the navigation bar’s stack, the value of this property is nil..

Which worked for my needs. Hope it helps, if not I am interested to hear how you solve it!

Solution 3:[3]

Beside check navigation stack, if the back button was hidden programmatically, you can check with this:

let isBackButtonHidden = self.navigationItem.hidesBackButton == true

Solution 4:[4]

There is a possible way but it's not the cleanest solution.

When looking at the subviews of a UINavigationBar there is a private view that is of type _UINavigationBarBackIndicatorView. If you were to access this directly your App would get rejected from the store.

However if no back button is added by the system this view will still remain but have the alpha value of 0.

By checking that the navigation bar contains no views that have the alpha value of zero allows the App to detect if a default back button is present or not.

__block BOOL backButtonIsHidden = NO;

[self.navigationBar.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull view, NSUInteger idx, BOOL * _Nonnull stop) {
    if(view.alpha == 0)
    {
        backButtonIsHidden = YES;
        *stop = YES;
    }
}];

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Prateek Surana
Solution 2 atom
Solution 3 Tony TRAN
Solution 4 Ste Prescott