Setting navigation bar back button image
Asked Answered
A

4

19

I want to set the back button in my UINavigationBar to this image:

enter image description here

I don't want the image to be embedded in the standard back button image, I just want this image to appear.

I know from looking at other questions that I can use:

[[UIBarButtonItem appearance] setBackButtonBackgroundImage:barButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

to set the background image of the back button. But this causes the image to be stretched, and this particular image is not, as far as I can tell, suitable to be stretched.

Is there a way that I can replace back button image with my image?

I am supporting iOS 5.0 and up.

Albright answered 27/4, 2013 at 16:31 Comment(0)
T
5

From the docs for UIBarButtonItem setBackButtonBackgroundImage:forState:barMetrics::

For good results, backgroundImage must be a stretchable image.

So, make it stretchable. I.e. specify which parts of the image can be stretched, and more importantly, which parts can not be stretched. In your case this will be the edges of the image (the part not containing the arrow).

UIImage resizableImageWithCapInsets:

The alternative is to supply a number of images (one for each bar metric) which is of a size that means it won't need to be scaled. raywenderlich user-interface-customization. But you're still going to want to make the image stretchable so you have control over what happens.

If you can't find a stretch spec which works, your fallback position is to create a template back button item for each instance of each view controller and set it as the backBarButtonItem for its navigation item.

Thermel answered 27/4, 2013 at 16:46 Comment(6)
Thanks for your reply and the documentation link. I am familiar with making stretchable images, but you can see from my image that it will not look good if stretched horizontally. I want to know if I can replace the button image, not just set the background image.Albright
When creating the stretchable image you specify which parts are and aren't stretched. You just need to set that the section of the image containing the arrow is not stretched and the edges around it are.Thermel
Oh I see, sorry I misread your answer. But is it possible to not stretch the center of an image, and allow stretching of the edges? I thought resizableImageWithCapInsets allowed you to set edges of the image that won't be stretched. How can I create an image in which the edges are stretchable but the center is not?Albright
I can do with reading more carefully too :-) You can set the stretch to treat the arrow as a 'corner' section of the image but the offset you get might not look great depending on the size of the original and how much it gets stretched.Thermel
OK thanks. Your answer is pretty much in line with what I was thinking, but I wanted to confirm it.Albright
How does this solution remove the text on the back button? I have the same problem (didn't want to start a new question). I used a workaround to set the alpha of the back button titleLabel.. Is there a proper way to set the back button to an image only (using the appearance proxy preferably)?Heathenry
B
48

Since iOS 7+ you should use backIndicatorImage property of UINavigationBar to set your custom indicator image. Also you need to provide backIndicatorTransitionMaskImage(you may use the same image for both).

Swift:

UINavigationBar.appearance().backIndicatorImage = UIImage(named: "back-button-image")
UINavigationBar.appearance().backIndicatorTransitionMaskImage = UIImage(named: "back-button-image")

Objective-C:

[[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@"back-button-image"]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"back-button-image"]];
Bootleg answered 10/10, 2013 at 15:0 Comment(0)
T
5

From the docs for UIBarButtonItem setBackButtonBackgroundImage:forState:barMetrics::

For good results, backgroundImage must be a stretchable image.

So, make it stretchable. I.e. specify which parts of the image can be stretched, and more importantly, which parts can not be stretched. In your case this will be the edges of the image (the part not containing the arrow).

UIImage resizableImageWithCapInsets:

The alternative is to supply a number of images (one for each bar metric) which is of a size that means it won't need to be scaled. raywenderlich user-interface-customization. But you're still going to want to make the image stretchable so you have control over what happens.

If you can't find a stretch spec which works, your fallback position is to create a template back button item for each instance of each view controller and set it as the backBarButtonItem for its navigation item.

Thermel answered 27/4, 2013 at 16:46 Comment(6)
Thanks for your reply and the documentation link. I am familiar with making stretchable images, but you can see from my image that it will not look good if stretched horizontally. I want to know if I can replace the button image, not just set the background image.Albright
When creating the stretchable image you specify which parts are and aren't stretched. You just need to set that the section of the image containing the arrow is not stretched and the edges around it are.Thermel
Oh I see, sorry I misread your answer. But is it possible to not stretch the center of an image, and allow stretching of the edges? I thought resizableImageWithCapInsets allowed you to set edges of the image that won't be stretched. How can I create an image in which the edges are stretchable but the center is not?Albright
I can do with reading more carefully too :-) You can set the stretch to treat the arrow as a 'corner' section of the image but the offset you get might not look great depending on the size of the original and how much it gets stretched.Thermel
OK thanks. Your answer is pretty much in line with what I was thinking, but I wanted to confirm it.Albright
How does this solution remove the text on the back button? I have the same problem (didn't want to start a new question). I used a workaround to set the alpha of the back button titleLabel.. Is there a proper way to set the back button to an image only (using the appearance proxy preferably)?Heathenry
M
5

swift version :-

    self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: "HomeLeft@2x")
    self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "HomeLeft@2x")
    self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)

put this in viewDidLoad()

Maragretmarala answered 19/10, 2015 at 9:9 Comment(0)
T
0

For Swift 3

In ViewDidLoad paste this

let backBtn = UIBarButtonItem()
let image: UIImage = UIImage(named: "your_image_name")!
backBtn.image = image
backBtn.action = #selector(popSelf)
backBtn.target = self
navigationItem.leftBarButtonItem = backBtn

create following function,

func popSelf() {
    navigationController?.popViewController(animated: true)
    // do your stuff if you needed
}
Tambac answered 18/10, 2016 at 10:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.