Learning iOS UINavigationItems: Back Bar Buttons

Here's a tip for the iOS beginners among us:  Just because something is on the left doesn't mean it's called Left.  LeftBarButtonItem, for example, might just take you down the wrong path if you’re not careful.

Let's say you are wanting to show customized text on the button that shows up on the left side of the navigation bar in an iOS app.  In an unmodified Master-Details iPhone app, it is the button that returns you to the Master table view screen from within the Details view.

By default, that button displays the Title text from the previous ViewController.  The key word there is 'previous'.  Setting that text requires that you do so in the ViewController that executed the pushViewController call that got you to the next screen (Master, in this case).

So, there are two pieces to get correct here:  you must make your modification in the right place (the previous ViewController), and you have to access the correct button.  The correct button in this case is the navigationItem.backBarButtonItem.  So the following will work if added in the MasterViewController.  Remember, make the change in the view you want to return to using the 'My Custom Text' button.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{

    if (!self.detailViewController) {

        self.detailViewController = [[[DetailViewControlleralloc] initWithNibName:@"DetailViewController" bundle:nil] autorelease];

       

}

    self.navigationItem.backBarButtonItem = [[[UIBarButtonItemalloc] initWithTitle:@"My Custom Text"style:UIBarButtonItemStyleBordered target:nil action:nil] autorelease];

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

}

Notice how this also gives you the nice arrow shape on the button, which has nothing to do with the style parameter, but is part of the backBarButtonItem itself.

If you had used leftBarButtonItem in the exact same place, however, you wouldn't see any effect at all on the Details screen.  That's because leftBarButton shows on the current view, not the next one in the stack.  So you would see a square button, not an arrow button…and it would be on the wrong screen!  If you did want to see a button in that location that was NOT a back button, this would be useful - but probably not in the didSelectRowAtIndexPath method.  Place there, the button doesn't show up until you leave the view and come back!

self.navigationItem.leftBarButtonItem = [[[UIBarButtonItemalloc] initWithTitle:@"My Custom Text"style: UIBarButtonItemStyleBorderedtarget:nil action:nil] autorelease];

So, given all this explanation, you might think that you can just use leftBarButtonItem from the Details ViewController.  If you do so, you will lose both the arrow shape of the button and the 'Back' navigation from the button itself.  So, only go that route if you want to replace the Back functionality altogether. 

For example, we could do this:

self.detailViewController.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"My Custom Text"style: UIBarButtonItemStyleBordered target:nil action:nil] autorelease];

To get a square button that replaces the Back button entirely.

 

Notice that we were able to do all of these manipulations without altering the Title property of either of our ViewControllers.  While it is possible to change Back button text by using Title, I think you'll find that method pretty clumsy.  In my tests, the Title text was quite visibly changing during the navigation animation - not a pretty result at all.  To learn more about button manipulation inside NavigationItems, you can view the full documentation here.

comments powered by Disqus