Customize the Back Button of UINavigationItem in the Navigation Bar
I’ve recently noticed a pattern of developers having trouble customizing the back button in the navigation bar. If you’re reading this, the problem may sound familiar.
When you use a UINavigationController to create a navigation stack, iOS conveniently and automatically creates a back button having the title that is the title of the previous view controller or the word Back if the previous view controller has no title. Of course, many times you want to override that default title or perhaps even use an image in its place. Let’s use Apple’s Master-Detail Application template as an example.
Let’s assume that instead of the word back or the title of the MasterViewController, you wanted to use the word Previous. You’ve looked at the UINavigationItem documentation and so in the - viewDidLoad
method DetailViewController, you create an instance of UIBarButtonItem with the title Previous, and then set the backBarButtomItem
property of the detail view controllers’s UINavigationItem to this bar buttom item you created.
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Previous" style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backButtonItem;
}
You then run your app and ¡Viola! … a big disappointment as nothing seemed to happen. You’ve double-checked your code, you read the docs again, you move the statements to - viewWillAppear
and - viewDidLoad
and still nothing.
So what most developers do that have gotten stuck here is create a custom bar button item and set the left button of the navigation item to it. However, then you get a square button instead of the button with the triangular end. So then the graphics designer gets involved and creates a custom image which developers then use to create a custom UIButton to use as a custom view for the hand-spun back button. The developers aren’t happy with it, it seems like a hack, especially given that Apple’s documentation clearly says you can customize the back button! WTF???
Now I think that taken as a whole, Apple’s documentation of the Cocoa and iOS frameworks are the best of any framework documentation. Easy to read, very description, easy to navigate (although, I wonder why searching web version is so much faster than the local version within Xcode). Occasionally, however, Apple makes you read between the lines when an additional sentence or two would save some developers a few hair-pulling incidents. The documentation for the backButtonItem
property is one of those times. Let’s look at the description:
When this navigation item is immediately below the top item in the stack, the navigation controller derives the back button for the navigation bar from this navigation item. When this property is nil, the navigation item uses the value in its title property to create an appropriate back button. If you want to specify a custom image or title for the back button, you can assign a custom bar button item (with your custom title or image) to this property instead. When configuring your bar button item, do not assign a custom view to it; the navigation item ignores custom views in the back bar button anyway.
It’s very important to read the first sentence carefully, “When this navigation item is immediately below the top item in the stack… .” What this is saying, and what developers sometimes miss, is that the back button is NOT set in navigation item of the visible view controller, but instead, it is set in the navigation item of the previous view controller. This throws everyone off because the rest of the items in the navigation bar is controlled by the navigation item of the visible view controller. As you can see, the documentation says that the back button in the bar is derived from the back button item in the navigation item immediately below the top item in the stack.
Going back to the MasterDetail example application, this means that the statements in the - viewDidLoad
statement belong in the - viewDidLoad
method in MasterViewController.
Also, make sure to notice that you cannot create a custom view to use for the back button. Custom views are ignored. You can still set the background image of the back bar button item with the – setBackButtonBackgroundImage:forState:barMetrics:.
This tip also published on my blog, Objective-Ramblings
Written by Daniel Brajkovic
Related protips
6 Responses
Thanks - I was tearing my hair out and didn't realise I had to set the property in the previous view!
I have a proble,
In my application
I want back arrow with written as a Back.
I have not set any back button code. I and I have nt set any title on my master view controller.
Still Back arrow comes but back text does not come, in iOS 10.
It is solved now, In app delegate, our team has written the code to hode back title.
*hide
Is there a swift version of this? Tanks =]