Wednesday, October 15, 2014

iOS Set Navigation Bar Back Button Title

In summary, to set the back button title of the current ViewController, we create a backBarButtonItem for the previous ViewController.


situee.blogspot.com



Problem


But I found that setting the  navigationBar.topItem.backBarButtonItem in ViewWillAppear does not work.

An answer using topItem is marked as correct in stackoverflow.

But according to the document, we should use backItem. 
Why topItem works? While backItem not work.

Reason


The reason is that topItem and backItem are still NOT updated in viewWillAppear.
The topItem still pointing to the previous viewController navigationItem.

In viewWillLayoutSubviews, the topItem and backItem are updated. So we can use backItem from viewWillLayoutSubviews.

The viewController life cycle are 

loadView
viewDidLoad
viewWillAppear
viewWillLayoutSubviews
viewDidLayoutSubviews
viewDidAppear
.................
viewWillDisappear
viewDidDisappear
viewWillAppear
viewWillLayoutSubviews
viewDidLayoutSubviews
viewDidAppear

Debug and Analysis

Environment: Xcode 5.1.1 - iOS 7.1 iPhone Simulator

2014-10-16 10:31:02.891 xxxxApp[1176:60b] -[ViewController viewWillAppear:]
2014-10-16 10:31:02.891 xxxxApp[1176:60b] previous.navigationItem = <UINavigationItem: 0xcb92050>
2014-10-16 10:31:02.892 xxxxApp[1176:60b] previous.navigationItem.backBarButton = (null)
2014-10-16 10:31:02.892 xxxxApp[1176:60b] self.navigationItem = <UINavigationItem: 0x14167e30>
2014-10-16 10:31:02.892 xxxxApp[1176:60b] navigationBar.topItem = <UINavigationItem: 0xcb92050>
2014-10-16 10:31:02.892 xxxxApp[1176:60b] navigationBar.backItem = (null)
2014-10-16 10:31:02.893 xxxxApp[1176:60b] topItem.backBarButton = (null)
// set topItem.backBarButtonItem here
2014-10-16 10:31:02.893 xxxxApp[1176:60b] topItem.backBarButton = <UIBarButtonItem: 0x14160e00>
2014-10-16 10:31:02.893 xxxxApp[1176:60b] previous.navigationItem.backBarButton = <UIBarButtonItem: 0x14160e00>

In viewWillAppear,
* previous.navigationItem ==  navigationBar.topItem
* navigationBar.backItem == null (because the previous viewcontroller is the rootViewController here)
* after setting topItem.backBarButton, previous.navigationItem has the same back button.



2014-10-16 10:31:02.905 xxxxApp[1176:60b] -[ViewController viewWillLayoutSubviews]
2014-10-16 10:31:02.905 xxxxApp[1176:60b] previous.navigationItem = <UINavigationItem: 0xcb92050>
2014-10-16 10:31:02.905 xxxxApp[1176:60b] previous.navigationItem.backBarButton = <UIBarButtonItem: 0x14160e00>
2014-10-16 10:31:02.906 xxxxApp[1176:60b] self.navigationItem = <UINavigationItem: 0x14167e30>
2014-10-16 10:31:02.906 xxxxApp[1176:60b] navigationBar.topItem = <UINavigationItem: 0x14167e30>
2014-10-16 10:31:02.906 xxxxApp[1176:60b] navigationBar.backItem = <UINavigationItem: 0xcb92050>
2014-10-16 10:31:02.907 xxxxApp[1176:60b] topItem.backBarButton = (null)
// set topItem.backBarButtonItem here
2014-10-16 10:31:02.907 xxxxApp[1176:60b] topItem.backBarButton = <UIBarButtonItem: 0x1417dda0>
2014-10-16 10:31:02.908 xxxxApp[1176:60b] previous.navigationItem.backBarButton = <UIBarButtonItem: 0x14160e00>


In viewWillLayoutSubviews,
* previous.navigationItem ==  navigationBar.backItem
* after setting topItem.backBarButton, previous.navigationItem.backBarButton is NOT changed.
* previous.navigationItem.backBarButton is still the button set in viewWillAppear.

Solution


-(void)viewWillLayoutSubviews{
    navigationController.navigationBar.backItem.backBarButtonItem 
=[[UIBarButtonItem alloc]
     initWithTitle:backButtonTitle
     style:UIBarButtonItemStylePlain
     target:self
     action:nil];
}

or

You can set the back button of previous viewcontroller navigationITem in like this
It can be in viewDidLaod, viewWillAppear ...





Reference : 



Updating the Navigation Bar


 For all but the root view controller on the navigation stack, the item on the left side of the navigation bar provides navigation back to the previous view controller. The contents of this left-most button are determined as follows:

 - If the new top-level view controller has a custom left bar button item, that item is displayed. To specify a custom left bar button item, set the leftBarButtonItem property of the view controller’s navigation item.
 - If the top-level view controller does not have a custom left bar button item, but the navigation item of the previous view controller has an object in its backBarButtonItem property, the navigation bar displays that item.

 - If a custom bar button item is not specified by either of the view controllers, a default back button is used and its title is set to the value of the title property of the previous view controller—that is, the view controller one level down on the stack. (If there is only one view controller on the navigation stack, no back button is displayed.)


Document of UINavigationBar.backItem


  @property(nonatomic, readonly, retain) UINavigationItem *backItem

Description
The navigation item that is immediately below the topmost item on navigation bar’s stack. (read-only)

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.




1 comment:

  1. Discover how to customize the back button title in your iOS app's navigation bar with our step-by-step guide. Whether you're building a new app or updating an existing one, providing users with clear and meaningful navigation is essential for a seamless user experience. https://www.mobilezmarket.com/

    ReplyDelete