Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting a Custom Image for a Back Button on UINavigationBar

I am trying to set a custom image for the back button that automatically gets place onto a navigation bar when a new view is pushed onto the stack.

I have tried adding the following in the viewDidLoad of the parent viewController:

[[UIBarButtonItem appearance] setBackButtonBackgroundImage:[UIImage imageNamed:@"BackButton.png"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

I have also tried the following:

UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"BackButton.png"] style:UIBarButtonItemStyleBordered target:nil action:nil];
    self.navigationItem.backBarButtonItem = btn;

Using UIAppearance produces quite strange results: The BackButton image seems to be placed underneath the original title

like image 557
Paul Morris Avatar asked Jun 13 '12 17:06

Paul Morris


People also ask

How do you customize navigation buttons?

6. To customize quick shortcut on the left side of the navigation bar, scroll down and tap on “Type”, below “Extra left button”. Here, you can choose any shortcut you want. It will be assigned to the left side of the navbar.

How do I change the navigation bar on my Iphone 12?

A user changes the navigation bar's style, or UIBarStyle , by tapping the “Style” button to the left of the main page.

How do I customize the navigation bar in Swift?

Go to the ViewController. swift file and add the ViewDidAppear method. a nav helper variable which saves typing. the Navigation Bar Style is set to black and the tint color is set to yellow, this will change the bar button items to yellow.


4 Answers

try this code

UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];  
UIImage *backBtnImage = [UIImage imageNamed:@"BackBtn.png"]  ;  
[backBtn setBackgroundImage:backBtnImage forState:UIControlStateNormal];  
[backBtn addTarget:self action:@selector(goback) forControlEvents:UIControlEventTouchUpInside];  
backBtn.frame = CGRectMake(0, 0, 54, 30);  
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:backBtn] ;  
self.navigationItem.leftBarButtonItem = backButton;

then define goback method like this

- (void)goback
{
    [self.navigationController popViewControllerAnimated:YES];
}
like image 52
Piyush Kashyap Avatar answered Oct 26 '22 17:10

Piyush Kashyap


Since iOS 7.0 there is a new method in API backIndicatorImage. You can use it instead of setBackButtonBackgroundImage if you don't want the image to be stretched to fit the text (for example if you want a fixed size custom back arrow). Here's an example in swift:

let image = UIImage(named: "back_button")
    
UINavigationBar.appearance().backIndicatorImage = image
UINavigationBar.appearance().backIndicatorTransitionMaskImage = image

You can hide the text from the button using this trick:

UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -66), for: .default)

for Swift 5

var backButtonImage = UIImage(named: "back_button")

backButtonImage = backButtonImage?.stretchableImage(withLeftCapWidth: 15, topCapHeight: 30) UIBarButtonItem.appearance().setBackButtonBackgroundImage(backButtonImage, for: .normal, barMetrics: .default)

like image 23
Konstantine Kalbazov Avatar answered Oct 26 '22 19:10

Konstantine Kalbazov


This is the code I'm using and works perfectly in my own iOS 5 app. This code is from application:didFinishLaunchingWithOptions: in the app delegate:

UIImage * backButtonImage = [UIImage imageNamed: @"back-button-image"];
backButtonImage = [backButtonImage stretchableImageWithLeftCapWidth: 15.0 topCapHeight: 30.0];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage: backButtonImage forState: UIControlStateNormal barMetrics: UIBarMetricsDefault];

You'll may need to use a stretchable image, where the left facing "point" is the left cap


or in Swift

let backButtonImage = UIImage(named: "back-button-image")
backButtonImage = backButtonImage?.stretchableImageWithLeftCapWidth(15, topCapHeight: 30)
UIBarButtonItem.appearance().setBackButtonBackgroundImage(backButtonImage, forState: .Normal, barMetrics: .Default)
like image 27
Ashley Mills Avatar answered Oct 26 '22 18:10

Ashley Mills


iOS 8+ Swift version (can be converted to ObjC with not much effort). This method preserves all advantages and behaviour of navigation bar related to standard back button (animation on pushing/popping, interactive pop gesture, etc)

// Call the code ONE TIME somewhere on app launch to setup custom back button appearance
UINavigationBar.appearance().tintColor = UIColor.blackColor()
// If you need custom positioning for your back button, in this example button will be 1 px up compared to default one
// Also only vertical positioning works, for horizontal add offsets directly to the image
let backImageInsets = UIEdgeInsetsMake(0, 0, -1, 0)
// Get image, change of rendering (so it preserves offsets made in file), applying offsets
let backImage = UIImage(named: "YourButtonImageAssetFileName")?.imageWithRenderingMode(.AlwaysOriginal).imageWithAlignmentRectInsets(backImageInsets)
// Setting images
UINavigationBar.appearance().backIndicatorImage = backImage
UINavigationBar.appearance().backIndicatorTransitionMaskImage = backImage

// Call EACH TIME BEFORE pushing view controller if you don't need title near your back button arrow
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
// Push controller
self.navigationController?.pushViewController(vc, animated: true)
like image 27
Andrei Konstantinov Avatar answered Oct 26 '22 18:10

Andrei Konstantinov