8

I am trying to use a custom item for the back button in my navigation bar.

UIImage *backButtonImage = [UIImage imageNamed:@"backbutton.png"];
UIBarButtonItem *customItem = [[UIBarButtonItem alloc] initWithImage:backButtonImage style:UIBarButtonItemStylePlain target:nil action:nil];
[self.navigationItem setBackBarButtonItem: customItem];
[customItem release];

What I end up getting is my image with a border around it. It looks like this (My image is the back button):

Back Button

How can I get rid of the border? What am I doing wrong?

Moshe
  • 57,511
  • 78
  • 272
  • 425
Denny
  • 1,210
  • 3
  • 15
  • 26

4 Answers4

10

Building on Jorge's code, this is my solution.

I create a simple category on UIViewController:

UIViewController+ImageBackButton.h

#import <UIKit/UIKit.h>

@interface UIViewController (ImageBackButton)

- (void)setUpImageBackButton;

@end

UIViewController+ImageBackButton.m

#import "UIViewController+ImageBackButton.h"

@implementation UIViewController (ImageBackButton)

- (void)setUpImageBackButton
{
    UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 34, 26)];
    [backButton setBackgroundImage:[UIImage imageNamed:@"back_arrow.png"] forState:UIControlStateNormal];
    UIBarButtonItem *barBackButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    [backButton addTarget:self action:@selector(popCurrentViewController) forControlEvents:UIControlEventTouchUpInside];
    self.navigationItem.leftBarButtonItem = barBackButtonItem;
    self.navigationItem.hidesBackButton = YES;
}

- (void)popCurrentViewController
{
    [self.navigationController popViewControllerAnimated:YES];
}

@end

Now all you have to do is #import UIViewController+ImageBackButton.h in either all of your view controllers or in a custom base view controller class that your other view controllers inherit from and implement the viewWillAppear: method:

- (void)viewWillAppear:(BOOL)animated
{
    [self setUpImageBackButton];
}

That's all. Now you have an image back button everywhere. Without a border. Enjoy!

Johannes Fahrenkrug
  • 42,912
  • 19
  • 126
  • 165
  • 1
    This is a nice solution. I wonder if there is a way to dynamically detect when the standard back button is on screen to prevent having to override viewWillAppear every time. – Ivan Lesko Jul 25 '17 at 22:03
  • @IvanLesko That's a good question. I'm sure there must be a way. If you are desperate and all else fails you could iterate of the UINavigationBar's subviews. But that should be the last resort :) – Johannes Fahrenkrug Jul 26 '17 at 15:53
10

Your image is appearing inside of a back button and it is apparently (from your screenshot) not the same size as the back button.

You might want to hide the back button and then replace it with a "Left Bar Button" instead.

Code:

UIImage *backButtonImage = [UIImage imageNamed:@"backbutton.png"];
UIBarButtonItem *customItem = [[UIBarButtonItem alloc] initWithImage:backButtonImage style:UIBarButtonItemStylePlain target:self.navigationController action:@selector(popViewControllerAnimated:)];
[self.navigationController setHidesBackButton:YES];
[self.navigationItem setLeftBarButtonItem: customItem];
[customItem release];
Moshe
  • 57,511
  • 78
  • 272
  • 425
  • Thanks for your answer. I tried different image sizes, but none of them works. I always get a border around my scaled image. A similar thing happens if I use LeftBarButtonItem instead of BackBarButtonItem. Do you know of any example project that include working images and code? – Denny Jan 30 '11 at 19:24
  • No, I am not aware of any projects, but I may try to put one together later, this evening. – Moshe Jan 30 '11 at 19:34
6

Here's an updated version. This includes the setting the target, font size, etc.

Also, it reflects that setHidesBackButton is not available as a property of navigationController.

UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *backButtonBackgroundImg = [UIImage imageNamed:@"BackButton.png"];
backButton.frame = CGRectMake(0.0f, 0.0f, backButtonBackgroundImg.size.width, backButtonBackgroundImg.size.height);
[backButton setBackgroundImage:backButtonBackgroundImg forState:UIControlStateNormal];
[backButton addTarget:self action:@selector(didTouchUpInsideBackButton:) forControlEvents:UIControlEventTouchUpInside];
backButton.titleLabel.font = [UIFont boldSystemFontOfSize:[UIFont smallSystemFontSize]];
[backButton setTitle:@"MyTitle" forState:UIControlStateNormal];

self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];

Note that this is from an ARC project, so no releases etc. on the objects.

Max MacLeod
  • 26,115
  • 13
  • 104
  • 132
1

I created a category of UINavigationBar which I call in viewWillAppear in each of my viewControllers. The code that I use to change the appearance of my back button is the following:

UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake( your button frame)];
[backButton setBackgroundImage:[UIImage imageNamed:@"your image name"] forState:UIControlStateNormal];
UIBarButtonItem *barBackButtonItem = [[UIBarButtonItem alloc] initWithCustomView: backButton];
[backButton addTarget:delegate action:@selector(backButtonPressed) forControlEvents:UIControlEventTouchUpInside];
self.topItem.leftBarButtonItem = barBackButtonItem;
self.topItem.hidesBackButton = YES;

Works perfectly under iOS 6.

Jorge Perez
  • 1,606
  • 1
  • 13
  • 4