35

I have a custom UIBarButtonItem with an image that works fine in iOS 6.1. But iOS 7 has a tintColor and it overlays this color over my image. If I set the tintColor to [UIColor clearColor] the button doesn't show up all together.

How can I have my back button show up in iOS 7 as it does in iOS 6? Please help?

iOS 6.1

iOS 7

Majid
  • 383
  • 1
  • 3
  • 8
  • 2
    You should not use a bar button item as a back button. Instead set the `backIndicatorImage` for the navigation bar. – Felix Sep 20 '13 at 09:20
  • The app has to have the same look in all iOS versions. `backIndicatorImage` is for iOS 7 only. I already use a `mask` in iOS 6 `const float colorMask[6] = {222, 255, 222, 255, 222, 255}; UIImage *image = [UIImage imageWithCGImage: CGImageCreateWithMaskingColors([[UIImage alloc] init].CGImage, colorMask)]; [backButtonItem setBackgroundImage:image forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];` – Majid Sep 20 '13 at 09:41
  • I am using ios5, can U help me – chandru Dec 19 '13 at 08:09

6 Answers6

43

You should use appearance on UINavigationBar to globally set the custom back button.

[UINavigationBar appearance].backIndicatorImage = customBackButton;
[UINavigationBar appearance].backIndicatorTransitionMaskImage = customBackButton;
Johannes
  • 1,370
  • 16
  • 15
  • 8
    I would like to add that customBackButton image should use `imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal`, like this `[[UIImage imageNamed:@"imageName"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];` so it can show the color of the image. – Scar Sep 30 '15 at 10:46
  • 1
    Not valid for iOS 9: no backIndicatorImage – Eugene Braginets Apr 04 '16 at 08:23
  • @Sebastian You are right, fixed and forgot about that. Likely had typo there and autocompletion didn't work. Thanks for noting that! – Eugene Braginets Apr 24 '16 at 14:35
  • How to remove title in all back button when appearance? – Nike Kov Jan 04 '17 at 15:22
  • 2
    Xcode/Swift don't seem to know about these as they don't show in autocomplete, it compiles and runs though. – Brandon Haugen Feb 23 '18 at 22:53
23

Try to set UIBarButtonItem like this way in ios7:-

UIImage *temp = [[UIImage imageNamed:@"theImage"] imageWithRenderingMode: UIImageRenderingModeAlwaysOriginal];    
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithImage:temp style:UIBarButtonItemStyleBordered target:self action:@selector(action)];

Here is an original post in apple Dev center discussion Forums

For supporting both version iOS7 as well as lower then you check system-version and set code like:-

UIImage *temp=nil;

if([[[UIDevice currentDevice] systemVersion] floatValue] < 7.0)
{ 
    temp = [UIImage imageNamed:@"btn-back.png"]; 
}
else
{ 
    temp = [[UIImage imageNamed:@"btn-back.png"] imageWithRenderingMode: UIImageRenderingModeAlwaysOriginal];
 }
Nitin Gohel
  • 49,482
  • 17
  • 105
  • 144
  • Thank you, this works. However `UIImageRenderingModeAlwaysOriginal` doesn't work in iOS 6, I had to make a check for the iOS version. `UIImage *backImage = nil; if([[[UIDevice currentDevice] systemVersion] floatValue] < 7.0){ backImage = [UIImage imageNamed:@"btn-back.png"]; }else{ backImage = [[UIImage imageNamed:@"btn-back.png"] imageWithRenderingMode: UIImageRenderingModeAlwaysOriginal]; }` – Majid Sep 20 '13 at 09:36
  • thank you i just edit my answer for supporting both Version to help's other they stuck with same issue. – Nitin Gohel Sep 20 '13 at 09:54
  • also a minor thing, you should drop the .png in your images. that way ios can pick up retina and non retina images, or device specific images as well. – Michael Apr 15 '14 at 23:39
  • I believe respondsToSelector: would be more appropriate in this case. UIImage *temp = [UIImage imageNamed:@"btn-back.png"]; if ([temp respondsToSelector:@selector(imageWithRenderingMode:)]) { temp = [temp imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; } – christopherdrum Jun 16 '14 at 02:49
  • UIBarButtonItemStyleBordered is deprecated in iOS8.x. Use UIBarButtonItemStylePlain. – John Stack Nov 12 '14 at 02:44
20

The following seems to make a bit more sense for people who don't want to mess with the existing target action, etc. Just copy and paste. Also this forces iOS to use your image with all of its flairs -- as opposed to simply using a template/impression of the image.

- (void)setCustomNavigationBackButton
{
    UIImage *backBtn = [UIImage imageNamed:@"arrow"];
    backBtn = [backBtn imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    self.navigationItem.backBarButtonItem.title=@"";
    self.navigationController.navigationBar.backIndicatorImage = backBtn;
    self.navigationController.navigationBar.backIndicatorTransitionMaskImage = backBtn;
}

arrow is the name of your image.

learner
  • 11,490
  • 26
  • 97
  • 169
8

swift version:

var backBtn = UIImage(named: "return_menu")
backBtn = backBtn?.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)

self.navigationController!.navigationBar.backIndicatorImage = backBtn;
self.navigationController!.navigationBar.backIndicatorTransitionMaskImage = backBtn;
Bill Chan
  • 3,199
  • 36
  • 32
6

Try it this way:

self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleBordered target:nil action:nil];
self.navigationController.navigationBar.backIndicatorImage = [UIImage imageNamed:@"yourImageName.png"];
self.navigationController.navigationBar.backIndicatorTransitionMaskImage = [UIImage imageNamed:@"yourImageName.png"];

This will create an image mask in the global tint colour which will give you your own custom icon. Does not work for colour images.

Rob Phillips
  • 295
  • 3
  • 9
0

// ADDING IMAGE TO BUTTON

UIButton *refreshButton = [UIButton buttonWithType:UIButtonTypeCustom];
[refreshButton setFrame:CGRectMake(0,0,30,30)];
refreshButton.userInteractionEnabled = YES;
[refreshButton setImage:[UIImage imageNamed:@"yourimage.jpg"] forState:UIControlStateNormal];

// ASSIGNING THE BUTTON WITH IMAGE TO BACK BAR BUTTON

UIBarButtonItem *refreshBarButton = [[[UIBarButtonItem alloc] initWithCustomView:refreshButton] autorelease];
self.navigationItem.leftBarButtonItem = refreshBarButton;
Funny
  • 566
  • 5
  • 16