How do I change the title of the "back" button on a Navigation Bar

Viewed 208100

Currently the left bar button default value is the title of the view that loaded the current one, in other words the view to be shown when the button is pressed (back button).

I want to change the text shown on the button to something else.

I tried putting the following line of code in the view controller's viewDidLoad method but it doesn't seem to work.

self.navigationItem.leftBarButtonItem.title = @"Log Out";

What should I do?

Thanks.

37 Answers

Im new in iOS but I will provide my very simple answer of overriding the navigation controller class. I have simple override the push and pop methods and save the title of previous view controller. Sorry for pasting in js block. Was little confused how to past it in normal code block.

#import "MyCustomNavController.h"


@implementation MyCustomNavController {

    NSString *_savedTitle;
}

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated withBackBtnTitle:(NSString *)title {
    _savedTitle = self.topViewController.title;

    self.topViewController.title = title;
    [super pushViewController:viewController animated:animated];
}

- (UIViewController *)popViewControllerAnimated:(BOOL)animated {

    [self.viewControllers objectAtIndex:self.viewControllers.count - 2].title = _savedTitle;
    return [super popViewControllerAnimated:animated];
}

@end

Most of solutions kills the original style of BackButton (The left arrowed bar button) while adding a usual button with desired title.
So to keep the original style there are 2 ways:
1st: To use undocumented button style (110 or something like that) which I prefer not to do. But if you want you could find how to do it here, on stackoverflow.
2nd: To use I the Trenskow's idea. I liked it and I use it a bit changed.
Instead of overriding - (NSString*)title I've decided to keep the original title in the following way (which allows me to use nib's titles as well as given title at push state btw).

- (void)viewDidLoad {
    [super viewDidLoad];
    static NSString * backButtonTitle=@"Back"; //or whatever u want

    if (![self.title isEqualToString:backButtonTitle]){

        UILabel* customTitleView = [[UILabel alloc] initWithFrame:CGRectZero];
        customTitleView.text = self.title; // original title
        customTitleView.font = [UIFont boldSystemFontOfSize:20];
        customTitleView.backgroundColor = [UIColor clearColor];
        customTitleView.textColor = [UIColor whiteColor];
        customTitleView.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5];
        customTitleView.shadowOffset = CGSizeMake(0, -1);

        [customTitleView sizeToFit];

        self.navigationItem.titleView = [customTitleView autorelease];
        self.title = backButtonTitle; 
    }
}

This solution works good and it looks native. Also if use it in the viewDidLoad method it prevents execution more then 1 time.
Also I've tried a Jessedc's solution but it looks bad. It causes visible to user title bar change on the fly from original to BackButton's desired and back.

Swift 4
iOS 11.2
Xcode 9.2

TableViewController1  ---segue--->   TableViewController2

You can change the text of the back button in either TableViewController1 or TableViewController2.

Change the back button text inside TableViewController1:

1) In viewWillAppear():

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    let myBackButton = UIBarButtonItem()
    myBackButton.title = "Custom text"
    navigationItem.backBarButtonItem = myBackButton
}

For some reason, viewDidLoad() is too early to add the back button to the NavigationItem. To connect the two TableViewControllers, in the storyboard control drag from the TableViewCell in TableViewController1 to the middle of TableViewController2 and in the popup menu select Selection Segue > Show.

2) In tableView(_:didSelectRowAt:):

override func tableView(_ tableView: UITableView, didSelectRowAt: IndexPath) {

    let myButton = UIBarButtonItem()
    myButton.title = "Custom text"
    navigationItem.backBarButtonItem = myButton

    performSegue(withIdentifier: "ShowMyCustomBackButton", sender: nil)
}

To connect the two TableViewControllers, in the storyboard control drag from the little yellow circle above TableViewController1 to the middle of TableViewController2 and from the popup menu select Manual Segue > Show. Then select the segue connecting the two TableViewControllers, and in the Attributes Inspector next to "Identifier" enter "ShowMyCustomBackButton".

3) In the storyboard:

If you just need static custom text for the back button, select the NavigationItem for TableViewController1 (it has a < for an icon in the storyboard’s table of contents), then open the Attributes Inspector and in the “Back Button” field enter your custom text (be sure to tab out of that field for the change to take effect).


Change the back button text inside TableViewController2:

1) In viewWillAppear():

class MySecondTableViewController: UITableViewController {

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        let myBackButton = UIBarButtonItem(
            title: "<Custom text",
            style: .plain,
            target: self,
            action: #selector(goBack)  //selector() needs to be paired with an @objc label on the method
        )

        navigationItem.leftBarButtonItem = myBackButton
    }

    @objc func goBack() {
        navigationController?.popViewController(animated: true)
    }

To connect the two TableViewControllers, in the storyboard control drag from the TableViewCell in TableViewController1 to the middle of TableViewController2 and in the popup menu select Selection Segue > Show.

If you have more than one navigation that is

ParentViewController --> ChildViewController1 --> ChildViewController2

you can use below code to change title of back button on navigation bar.

self.navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem.init(title: "Back", style: .plain, target: nil, action:nil)

This works for me in Swift 4 and iOS 11. Most commonly I need to do this when the user taps on a row in a table view and a new view controller is pushed onto the navigation stack. Usually I want the back button to be the name or some attribute of the object represented by the row that was tapped. So I usually do this in didSelectRowAt... like this:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let object = // get the object this row represents

    let backButton = UIBarButtonItem()
    backButton.title = object.name // or whatever
    self.navigationItem.backBarButtonItem = backButton

    // now show or segue to the next view controller
}

iOS 11+ solution - Doesn't require to create backbutton again.

Set backButtonTitle as a space on the previous screen.

// If navigation is from A -> B, set in A's `viewDidLoad`.
navigationItem.backButtonTitle = " "
Related