Take the 2-minute tour ×

I'm trying to customize the backBarButtonItem with a custom image (the text 'back' is included in that image), here is the current result:


Does anyone know why this might be happening?

Here is my code on viewDidLoad (actually runs both on the parent controller and then again on the new controller that has the back button)

UIImage *backButtonImage = [UIImage imageNamed:@"Graphics/Shared/navigation_back_button.png"];

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] 

self.navigationItem.backBarButtonItem = backButton;

Edit: I'm using iOS 5 by the way! Maybe appearance proxy is usable but so far when I tried to use it for the back button stuff (in appDelegate) the app simple crashes.

share|improve this question
be sure to approve the appropriate answer! –  Sir Kaydian Jun 6 '12 at 2:02
add comment

5 Answers

up vote 10 down vote accepted

Okay I solved the issue, using a bit of a rough trick, but at least it works. If anyone does come up with a more standard solution though, please let me know!

Here's my code:

UIImage *backButtonImage = [[UIImage imageNamed:@"Graphics/Shared/navigation_back_button.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage  forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, backButtonImage.size.height*2) forBarMetrics:UIBarMetricsDefault];

This is in my appdelegate's method:


To stop it stretching when using it as a background, I used the idea from iOS 5 XCODE 4.3.2 How to implement a custom (image) back button

But then tweaked it so rather than having to set-

self.title = @" ";

On every view load (and that might also mess with the nav bar title itself)

I just set the offset for the 'back' button text to twice the image height, so you'll never see it.

Why go to all this trouble, rather than use a left button item with it's own method to pop the view controller?

The main reason is that you lose the standard back button sliding animation for changing views. Also, this means I don't need to use a custom button or write a custom method for going back. It simply just works.

Hope this solves someone else's problem too, I know I was stuck on it for a good 3 hours!

share|improve this answer
great solution,good job! –  Claus Jul 8 '13 at 13:16
check my answer which avoid the image-stretching and title-position-adjust issue. –  Gon Feb 13 at 14:17
add comment

The "UIBarButtonItemStylePlain" designation specifies a button style.

Try creating your back button this way instead:

CGRect frameimg = CGRectMake(0, 0, backButtonImage.size.width, backButtonImage.size.height);
UIButton *someButton = [[UIButton alloc] initWithFrame:frameimg];
[someButton setBackgroundImage:backButtonImage forState:UIControlStateNormal];
// you have to do your own backButtonAction to pop the view controller, b.t.w.
[someButton addTarget:self action:@selector(backButtonAction:)
[someButton setShowsTouchWhenHighlighted:YES];

UIBarButtonItem *backButton =[[UIBarButtonItem alloc] initWithCustomView:someButton];
[someButton release];

self.navigationItem.backBarButtonItem = backButton;
share|improve this answer
Thanks for the attempt Michael, but when I use your code the back button simply reverts completely the normal blue style with no customization. (I think I've tried a lot of variants similar to this method already) I notice from your 'release' line of code that I should point out I'm using iOS 5! So this probably changes a lot, my mistake for not making that clear originally. –  Dom Chapman Jun 6 '12 at 2:46
Apple's docs state: 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. –  Ashley Mills Jul 12 '13 at 9:20
@AshleyMills is quite right. This answer only works for leftBarButtonItem and rightBarButtonItem, not for backBarButtonItem. –  Gon Feb 13 at 14:04
add comment

In this case I found it easier to replace the barButtonItem, simply with a custom button.

Not exactly sure how you have designed you project, but it worked for me.

The setting for the custom button

The back button, resulting look

Then attach this code to it:

//go back to the previous screen


[self dismissModalViewControllerAnimated:YES];

share|improve this answer
That's all good but then I lose the standard sliding animation when I pop the view controller. It also happens for this project I'm not using interface builder or nib/xib files at all. I'm programmatically creating everything. –  Dom Chapman Jun 6 '12 at 2:44
Not really anwering his question. You lose the ability to use and utilize the standard UINavigationBar –  Avraham Shukron Aug 18 '12 at 8:29
add comment

To call

self.navigationItem.leftBarButtonItem = [CustomBarButton createNavBackBarButtonItemWithTitle:NSLocalizedString(@"Back", @"") target:self action:@selector(actionBack:)];

CustomBarButton has createNavBackBarButtonItemWithTitle class function

+(UIBarButtonItem *)createNavBackBarButtonItemWithTitle:(NSString *)t target:(id)tgt action:(SEL)a
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
// Since the buttons can be any width we use a thin image with a stretchable center point
UIImage *buttonImage = [[UIImage imageNamed:@"back_button_up.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:0];
UIImage *buttonPressedImage = [[UIImage imageNamed:@"back_button_over.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:0];

[[button titleLabel] setFont:[UIFont boldSystemFontOfSize:12.0]];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateHighlighted];
//[[button titleLabel] setShadowOffset:CGSizeMake(0.0, 1.0)];

CGRect buttonFrame = [button frame];
buttonFrame.size.width = [t sizeWithFont:[UIFont boldSystemFontOfSize:12.0]].width + 24.0;
buttonFrame.size.height = buttonImage.size.height;
[button setFrame:buttonFrame];

[button setBackgroundImage:buttonImage forState:UIControlStateNormal];
[button setBackgroundImage:buttonPressedImage forState:UIControlStateHighlighted];

[button setTitle:[NSString stringWithFormat:@"  %@",t] forState:UIControlStateNormal];

[button addTarget:tgt action:a forControlEvents:UIControlEventTouchUpInside];

UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:button];

return [buttonItem autorelease];
share|improve this answer
add comment

I tried it a lot today and got this solution. It separated background image and button image, seems easier and not that tricky.

UIImage *bgImage = [UIImage imageNamed:@"the-same-image-as-your-navbar-background-image"];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:bgImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:bgImage forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];

UIImage *buttonImage = [UIImage imageNamed:@"your-back-button-image"];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:buttonImage style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backButton;
share|improve this answer
add comment

Your Answer


