199

What I wanted to do is to remove the text from the 'Back' button of a UIBarButtonItem, leaving only the blue chevron on the navigation bar. Keep in mind that I'm developing for iOS 7. I've tried several methods, including, but not limited to:

This is the image method which I did not like (the image looked out of place):

UIBarButtonItem *barBtnItem = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"iOS7BackButton"] style:UIBarButtonItemStylePlain target:self action:@selector(goToPrevious:)];
self.navigationItem.leftBarButtonItem = barBtnItem;

Another method I tried was this, which simply did not work (nothing was displayed):

UIBarButtonItem *barBtn = [[UIBarButtonItem alloc]init];
barBtn.title=@"";
self.navigationItem.leftBarButtonItem=barBtn;

What I wanted to achieve is something like the back buttons found in the iOS 7 Music app, which only featured a single chevron.

Thanks.

3
  • look at this answer stackoverflow.com/a/20300577/1589731 Jul 3, 2014 at 16:26
  • Why don't you take image of what is your requirement? And refer it in leftBarButtonItem. Sep 18, 2015 at 8:19
  • The reason why I didn't use the picture method is 1. It's very hard to get a perfect picture of the back button and 2. There will be some form of misalignment with the image and it doesn't look natural, and that's why I took to StackOverflow for help on how to accomplish this natively.
    – Pan Ziyue
    Sep 18, 2015 at 8:25

39 Answers 39

412

To set the back button title for a view controller without changing its title use:

Objective-C:

self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:self.navigationItem.backBarButtonItem.style target:nil action:nil];

Swift:

navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)

To be clear, this is done on the view controller that you would see if you hit the back button. i.e. instead of seeing '< Settings' you want to just see '<' then on your SettingsViewController you would put this in your init. Then you don't get any of the problems of the title not showing when you're looking at the view controller itself.

21
  • 1
    I don´t know why the other answer is marked as correct, its just removing the title so the back button doent has a "title" to show, but thats not the correct approach at all! This one should be the right answer.
    – Pach
    May 15, 2014 at 11:13
  • 8
    Also to anyone using Swift, it's navigationItem.backBarButtonItem = UIBarButtonItem(title:"", style: .Plain, target: nil, action: nil). Not hard to convert from Obj-C to Swift, but I'll save you the troublef
    – Zoyt
    Jun 30, 2014 at 20:32
  • 15
    @BenjaminPiette are you calling this on the UIViewController that you would see if you hit the back button? Not the UIViewController that displays the back button.
    – DonnaLea
    Oct 22, 2014 at 16:07
  • 2
    What an elegant solution! Thanks. It just didn't feel right to do the offset thing.
    – Hyder
    Oct 7, 2015 at 6:34
  • 2
    this solution works perfect if you write this line of code on previous controller in navigation stack. Feb 24, 2017 at 10:12
198
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(-60, -60)
                                                         forBarMetrics:UIBarMetricsDefault];

Then you can remove the back button item title.

If you use Storyboard, you can set navigation attributes inspector Back Button with space.

17
  • 96
    There is a problem with large titles: they are not centered but pushed to the right, like if the back button text was still there
    – sonxurxo
    Jul 15, 2014 at 15:10
  • 11
    This doesn't work if the user has turned on "Accessibility - Button shapes" Nov 21, 2014 at 8:40
  • 22
    I think this is a better answer : [[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateNormal];
    – benjamin
    Jul 29, 2015 at 14:52
  • 19
    Any solution with magic numbers in it is a bad idea. With the push to autolayout, size classes, accessibility features, etc.. using constant values like this is bound to bite you. Mar 17, 2016 at 21:15
  • 3
    To improve upon benjamin's comment, you should set this for UIControlStateHighlighted as well
    – n_b
    Mar 24, 2016 at 19:54
127

If you are using Storyboards you can go to Attributes Inspector of the ViewController's Navigation Item (click on Navigation Bar) and set the Back Button property to " " (one space character). This will set the Back Button title to one space character, leaving the chevron visible. No need to mess with code.

example image

Note that this will set Back Button title for the Back Button that will segue to this View Controller from the one that was pushed on top of it, not for the Back Button that will be displayed inside this Controller!

1
  • 10
    I wish I could upvote this more: "Note that this will set Back Button title for the Back Button that will segue to this View Controller form the one that was pushed on top of it, not for the Back Button that will be displayed inside this Controller!" Sep 3, 2014 at 19:33
120

This works for me to display just the 'back' chevron without any text:

self.navigationController.navigationBar.topItem.title = @"";

Set this property in viewDidLoad of the View Controller presenting the navigation bar and it will do the trick.

Note: I have only tested it in iOS 7, which is within scope of the question.

11
  • 33
    That has a side effect of removing the title label in the middle of the navigation bar.
    – Pwner
    Dec 2, 2013 at 22:45
  • 7
    Set the title of the pushing VC on 'viewWillAppear' with the same property. This way it is not removed. Dec 3, 2013 at 0:41
  • 5
    I moved that piece of code to -viewDidLoad of the VC that I do not want the Back text. However, what I found out later on was that when I pop the 2nd VC from the navigationController the Title text appears shortly after, not immediately. I guess a video would illustrate this better so here it is: link
    – Pan Ziyue
    Feb 1, 2014 at 5:11
  • 1
    This is not the best answer, please refer to andyleehao's answer:[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) forBarMetrics:UIBarMetricsDefault];
    – lmnbeyond
    Jul 8, 2014 at 10:38
  • 1
    This is the correct answer as per Apple's documentation: "When the receiver is on the navigation item stack and is second from the top—in other words, its view controller manages the views that the user would navigate back to—the value in this property is used for the back button on the top-most navigation bar. If the value of this property is nil, the system uses the string “Back” as the text of the back button." May 3, 2016 at 7:21
28

enter image description here

Sometimes it is helpful to see things in context. Here is a minimal project that hides the "back" text but still shows the arrow.

Storyboard

enter image description here

There is a show segue from the "Show Second View Controller" button to the second view controller.

I also added a Navigation Item to the second view controller so that it would have a title. This is optional. It does not affect the back button.

Code

FirstViewController.swift

import UIKit
class FirstViewController: UIViewController {

    @IBAction func showSecondViewControllerButtonTapped(sender: UIButton) {

        // hide the back button text
        navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }
}

SecondViewController.swift

import UIKit
class SecondViewController: UIViewController {
    // Nothing at all needed here
}

Alternate method (IB only, no code)

On the storyboard select the navigation item for the first view controller (not the second). Just enter a space for the Back Button text.

enter image description here

1
  • Key concept that " for the first view controller (not the second)" as is the name of the VC that you want to come back so it's responsibility to give this title.
    – BuguiBu
    Oct 23, 2017 at 15:31
27

When you're setting the button's title, use @" " instead of @"".

--EDIT--

Does anything change when you try other strings? I'm using the following code myself successfully:

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:backString style:UIBarButtonItemStyleDone target:nil action:nil];
[[self navigationItem] setBackBarButtonItem:backButton];

backString is a variable that is set to @" " or @"Back", depending on if I'm on iOS 7 or a lower version.

One thing to note is that this code isn't in the controller for the page I want to customize the back button for. It's actually in the controller before it on the navigation stack.

2
  • Hmm, iOS 7 doesn't seem to change that. It keeps using "Back" as the title. If I put setLeftBarButtonItem:backButton instead nothing would be there.
    – Pan Ziyue
    Sep 30, 2013 at 16:07
  • 1
    If that's the case, and nothing happens when you set the title to something else, I think you'll have to try moving your code to the parent view controller. I'm using the code I posted above in my prepareForSegue method.
    – Kamaros
    Sep 30, 2013 at 16:30
15
self.navigationController.navigationBar.topItem.title = @"";
3
  • 1
    You can use backItem instead of topItem. TopItem will hide the title , while backItem will hide the back button title.
    – Ravi Ojha
    Nov 13, 2015 at 6:31
  • 2
    This is the only solution if the childViewController is at depth 2+ in the NavigationController's children stack
    – Nathaniel
    Feb 24, 2016 at 19:11
  • 2
    This will also remove the title of the previous view controller. In most cases, this is gonna suck
    – CalZone
    Apr 25, 2016 at 19:43
11

On iOS7, Apple introduced two new properties to UINavigationBar, 'backIndicatorTransitionMaskImage' and 'backIndicatorImage'.

By simply calling once:

[[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@"your_image"]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"your_image_mask"]];

It will render a custom image instead of the default chevron glyph, inheriting the keyWindow's tint color.

And for removing the title, I'll suggest Kamaros's answer. Remember to call this code on the view controller that's pushing your new view controller. Removing the title text of an iOS UIBarButtonItem

1
  • To adjust the tint colour [[UINavigationBar appearance] setTintColor:[UIColor whiteColor]]; Oct 31, 2013 at 2:21
10

I didn't have a lot of success with the provided answers but I did find a really simple work around. In your storyboard, you can click on your UIViewController's Navigation Item and set the back button text. I set it to a single ' ' space and it gave me the behavior I was looking for.enter image description here

10

This worked for me in iOS10. Call this from viewDidLoad of the view controller.

self.navigationController?.navigationBar.topItem?.title = ""
6

Simple solution to this problem, working on iOS7 as well as 6, is to set custom title view in viewDidLoad:

- (void)viewDidLoad {

    [super viewDidLoad];

    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    titleLabel.text = self.title;
    titleLabel.backgroundColor = [UIColor clearColor];

    [titleLabel sizeToFit];

    self.navigationItem.titleView = titleLabel;
}

Then, in viewWillAppear: you can safely call

self.navigationController.navigationBar.topItem.title = @" ";

Because your title view is custom view, it won't get overwritten when moving back in the navigation stack.

1
  • I only needed the latter part of the code and not the blank UILabel. I was calling [self.navigationItem.backBarButtonItem setTitle:@" "]; in viewWillAppear but it wasn't working on views presented after dismissing a modal view.
    – Diziet
    Jan 21, 2014 at 13:04
6

Actually you can do this with just one trick:

Override UINavigationBar class and add this line of code:

- (void)layoutSubviews{
    self.backItem.title = @"";
    [super layoutSubviews];
}

Then initialize your UINavigationController with this custom UINavigationBar class.. etc. UINavigationController * navController = [[UINavigationController alloc] initWithNavigationBarClass:[CBCNavigationBar class] toolbarClass:nil];

Hope this helps

3
  • This worked for me. Although it seems as if there is a slight stutter in the push animation on iOS 7: the title seems to make room for the back button then centers since there is none.
    – zekel
    Aug 7, 2014 at 19:40
  • Yeah, try using custom titleView instead of setting the navigationItem.title directly. I think that should fix your problem.
    – rordulu
    Aug 27, 2014 at 16:11
  • this solution is awesome cause it's globally for every navigationBar which has the sub-class. Thanks
    – Yetispapa
    Jun 7, 2017 at 8:14
5

I was able to cobble something together using DonnaLea's answer. This is how the solution appears in my UIViewController subclass:

var backItemTitle:String?

override func viewDidLoad() {
    super.viewDidLoad()

    //store the original title
    backItemTitle = self.navigationController?.navigationBar.topItem?.title

    //remove the title for the back button
    navigationController?.navigationBar.topItem?.title = ""
}

override func willMoveToParentViewController(parent: UIViewController?) {
    super.willMoveToParentViewController(parent)
    if parent == nil {

        //restore the orignal title
        navigationController?.navigationBar.backItem?.title = backItemTitle
    }
}

The problem with the original answer is that it removes the title from the controller when you pop back to it. Attempting to reset the title in viewWillDisappear is too late in the transition process; It causes the title to snap back in instead of animating nicely. However the willMoveToParentViewController happens sooner and allows for the correct behavior.

Caveat: I've only tested this with a normal UINavigationController push / pop. There might be additional unexpected behavior in other situations.

4

In the prepareForSegue: method of your first ViewController you set that views title to @"", so when the next view is pushed it will display the previous ViewController title which will be @"".

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    self.navigationItem.title = @" ";
}

The only problem with this is that when you hit the back button your previous view won't have a title, so you may add it again on viewWillAppear:

- (void)viewWillAppear:(BOOL)animated{
    self.navigationItem.title = @"First View Title";
}

I don't like very much this solution but it works and i didn't find other way to do it.

4

SWIFT 3

navigationController?.navigationBar.topItem?.title = ""
3

Non of the answers helped me. But a trick did - I just cleared the title of the view controller that pushed (where the back button is going to) just before pushing it.

So when the previous view doesn't have a title, on iOS 7 the back button will only have an arrow, without text.

On viewWillAppear of the pushing view, I placed back the original title.

1
  • 1
    Hmm, this trick works. However it looks like the words up there will flicker sometimes. Not a very good workaround but nevertheless a good one. +1
    – Pan Ziyue
    Oct 17, 2013 at 15:27
3

This is using subclass navigationController removes the "Back".

I'm using this to remove it, permanently through the app.

//.h
@interface OPCustomNavigationController : UINavigationController 

@end

//.m
@implementation OPCustomNavigationController

- (void)awakeFromNib
{
    [self backButtonUIOverride:YES];
}

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [self backButtonUIOverride:NO];

    [super pushViewController:viewController animated:animated];
}

- (void)backButtonUIOverride:(BOOL)isRoot
{
    if (!self.viewControllers.count)
        return;

    UIViewController *viewController;

    if (isRoot)
    {
        viewController = self.viewControllers.firstObject;
    }
    else
    {
        int previousIndex = self.viewControllers.count - 1;

        viewController = [self.viewControllers objectAtIndex:previousIndex];
    }

    viewController.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@""
                                                                                       style:UIBarButtonItemStylePlain
                                                                                      target:nil
                                                                                      action:nil];
}

@end
0
3
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefaultPrompt];
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(10.0, NSIntegerMin) forBarMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor],
                                                               NSFontAttributeName:[UIFont systemFontOfSize:1]}
                                                    forState:UIControlStateNormal];
3
  • 1
    Please, add explanation to your answer.
    – Alex
    Oct 28, 2015 at 7:06
  • 1 make the same color as the navigation bar 2 make the text size small enough not to squeeze the title
    – Bill Xie
    Oct 28, 2015 at 10:03
  • I reviewed your answer, you should always support your answer.
    – Alex
    Oct 28, 2015 at 10:05
3
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                [UIColor clearColor],UITextAttributeTextColor,
                                nil];
    
    [[UIBarButtonItem appearance] setTitleTextAttributes:attributes
                                                forState:UIControlStateNormal];

I was having a same problem and I did it this way.

--EDIT--

this is a solution when you really want to remove title text of all UIBarbuttonItem. If you only want to remove the title of the back bar button item, there is no one simple convenient solution. In my case, since I only have few UIBarButtonItems that need to show title text I just changed those specific buttons' titleTextAttributes. If you want to be more specific use the code below, which will only change navigation bar buttons:

NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                [UIColor clearColor],UITextAttributeTextColor,
                                nil];
    
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTitleTextAttributes:attributes
                                                forState:UIControlStateNormal];

--EDIT-- for swift

let BarButtonItemAppearance = UIBarButtonItem.appearance()
        BarButtonItemAppearance.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .normal)
        BarButtonItemAppearance.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .highlighted)
        BarButtonItemAppearance.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .selected)
3
  • 1
    This works for me, however you can briefly see the text when hitting back.
    – Diziet
    Jan 21, 2014 at 12:45
  • 3
    @Diziet try adding the same for the State UIControlStateHighlighted as well
    – CoderPug
    Jan 28, 2014 at 19:00
  • 2
    This works fine, but this also "hides" all other buttons, not only the Back Button... Any ideas to solve this?
    – Urkman
    Jan 28, 2014 at 21:08
2

Hide Back Button Title of Navigation Bar

UIBarButtonItem *barButton = [[UIBarButtonItem alloc] init];
barButton.title = @""; // blank or any other title
self.navigationController.navigationBar.topItem.backBarButtonItem = barButton;
2

Here's what I'm doing me, which is simpler to remove the title of back button

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.navigationBar?.backItem?.title = ""
}
0
2

Swift 3.1 You can do this by implementing the delegate method of UINavigationController. It'll hide the Title with back button only, we'll still get the back arrow image and default functionality.

func navigationController(_ navigationController: UINavigationController, 
  willShow viewController: UIViewController, animated: Bool) {
        let item = UIBarButtonItem(title: " ", style: .plain, target: nil, 
                    action: nil)
        viewController.navigationItem.backBarButtonItem = item
    }
0
1

You can also use this:

UIBarButtonItem *temporaryBarButtonItem = [[UIBarButtonItem alloc] init];
temporaryBarButtonItem.title = @"";
self.navigationItem.backBarButtonItem = temporaryBarButtonItem;

[temporaryBarButtonItem release];

This works for me

1
case : <Back as <

override func viewWillAppear(animated: Bool) {
navigationController!.navigationBar.topItem!.title = ""
    }
1

Perfect solution globally

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    UIBarButtonItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName:UIColor.clearColor()], forState: UIControlState.Normal)
    UIBarButtonItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName:UIColor.clearColor()], forState: UIControlState.Highlighted)

    return true
}
2
  • dumpest solution of all ... its also use space like before ... its just become transparent ...
    – Laszlo
    Oct 21, 2016 at 15:03
  • It removes the text from all the UIBarButtonItems of the app Oct 27, 2016 at 7:22
1

I create a custom class for UINavigationController and apply it to all of the navigation controllers in my app. Inside this custom UINavigationController class I set the UINavigationBar delegate to self once the view loads.

- (void)viewDidLoad {
    self.navigationBar.delegate = self;
}

Then I implement the delegate method:

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPushItem:(UINavigationItem *)item {

    // This will clear the title of the previous view controller
    // so the back button is always just a back chevron without a title
    if (self.viewControllers.count > 1) {
        UIViewController *previousViewController = [self.viewControllers objectAtIndex:(self.viewControllers.count - 2)];
        previousViewController.title = @"";
    }
    return YES;
}

This way I simply assign my custom class to all my navigations controllers and it clears the title from all the back buttons. And just for clarity, I always set the title for all my other view controllers inside viewWillAppear so that the title is always updated just before the view appears (in case it is removed by tricks like this).

1

Just entering a single space for the Back button navigation item works!!

1
  • 1
    This is more suitable as a comment than an answer. Feb 2, 2017 at 20:16
1

If like me you're using a custom view instead of the UINavigationBar and you're stuck with the back button then you have to do a bit of work that feels a bit cludgey.

[self.navigationController.navigationBar setHidden:NO];
self.navigationController.navigationBar.topItem.title = @"";
[self.navigationController.navigationBar setHidden:YES];

It seems like if it doesn't get presented then no matter what it'll try show a title, this means it's shown then hidden before it's drawn and solves the problem.

1
extension UIViewController{
    func hideBackButton(){
        navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }
}
1

This is better solution.

Other solution is dangerous because it's hack.

extension UINavigationController {

    func pushViewControllerWithoutBackButtonTitle(_ viewController: UIViewController, animated: Bool = true) {
        viewControllers.last?.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
        pushViewController(viewController, animated: animated)
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.