UINavigationBar barButtonItem change back button image and title - ios

Is it possible to change the back button on a UINavigationBar and change the title?
When I try to set the customView property, I get an image right next to the default button.
I use this code
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithImage:backButtonImage landscapeImagePhone:nil style:UIBarButtonItemStylePlain target:nil action:nil];
I want the title to be "Back" which is easy enough to do in Storyboard. But the problem is that no matter if I use code above or use customView property, the default back button remains.

You can add a UIImage to the UIButton. And, then use it as a custom back button. Here's a quick example:
// Custom image
UIImage *backButtonImage = [UIImage imageNamed:#"button-background-image.png"];
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[backButton setFrame:CGRectMake(0, 0, 100, 30)];
[backButton setBackgroundImage:backButtonImage forState:UIControlStateNormal];
// Custom title
[backButton setTitle:#"Back" forState:UIControlStateNormal];
[backButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
[backButton addTarget:self action:#selector(barPayButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[backButton setShowsTouchWhenHighlighted:NO];
UIBarButtonItem *buttonOnBar =[[UIBarButtonItem alloc] initWithCustomView:backButton];
self.navigationItem.leftBarButtonItem = buttonOnBar;
Note: You will loose the chevron (system-provided back arrow) which was introduced in iOS7. It goes as a title and chevron together presenting your previous view controller.
Update:
You can also use UIEdgeInsets to resize your image intelligently.
UIEdgeInsets edgeInsets = UIEdgeInsetsMake(0, 0, 15, 10);
UIImage *backButtonImage = [[UIImage imageNamed:#"button-background-image.png"] resizableImageWithCapInsets:edgeInsets];

You can achieve what you want by setting the navigationItem.leftBarButtonItem of the view controller that's being pushed to the custom bar button item with the look you want. Good Luck!

Related

Changing vertical position of UIBarButtonItem on iOS 8.2

Here is my navigation bar
I had a problem about changing vertical position of Settings UIBarButtonItem on my navigation bar. I would like to move the button item "Settings" down
Here is my code
UIBarButtonItem *settingsItem = [[UIBarButtonItem alloc] initWithTitle:#"Settings" style:UIBarButtonItemStylePlain target:self action:nil];
self.navItem.rightBarButtonItem = settingsItem;
[[UIBarButtonItem appearance] setTitlePositionAdjustment:UIOffsetMake(0,-10) forBarMetrics:UIBarMetricsDefault];
I had tried it again and again. It seemed that it's not work
Could anyone suggest me how to move the button item "Settings" down ?
You can easily add a Custom Button to your NavigationBarItem, Here is the way,
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; //create custom Button
[button setTitle:#"Settings" forState:UIControlStateNormal];
[button.titleLabel setFont:[UIFont systemFontOfSize:14.0]];
[button setTitleColor:[UIColor colorWithRed:179.0/255.0 green:40.0/255.0 blue:18.0/255.0 alpha:1] forState:UIControlStateNormal];
button.frame = CGRectMake(0, 0, 50, 20); //Button frame
[button addTarget:self action:#selector(yourCustomSelectorHere) forControlEvents:UIControlEventTouchUpInside]; //Add action method to the button here
UIView *backButtonView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 63, 33)];
backButtonView.bounds = CGRectOffset(backButtonView.bounds, -14, -7);
[backButtonView addSubview:button];
UIBarButtonItem *barBtnItem = [[UIBarButtonItem alloc]initWithCustomView: backButtonView]; //set button as UIBarButtonItem
self.navigationItem.rightBarButtonItem = barBtnItem; //set barBtnItem to rightBarButtonItem
By changing backButtonView.bounds values you can change the origin of the Button
Cited from apple's documentation on UIAppearance protocol
iOS applies appearance changes when a view enters a window, it doesn’t
change the appearance of a view that’s already in a window.
So if your code of setting UIBarButtonItem's appearance is after the navigationItem assignment code. It won't work

How to globally customize back button?

Following up on this question, where the accepted answer describes a way to globally customize the UINavigationController's back button, using this code in the implementation of a category named UINavigationItem+MyBackButton.h:
#import "UINavigationItem+MyBackButton.h"
#implementation UINavigationItem (MyBackButton)
-(UIBarButtonItem*)backBarButtonItem
{
UIBarButtonItem *backButton = [[UIBarButtonItem alloc]
initWithTitle: #"Back Button Text"
style: UIBarButtonItemStyleBordered
target: nil action: nil];
return [backButton autorelease];
}
#end
This code works fine for me as long as I only want to customize the title. When I want to get down and dirty and try to customize the background image, just nothing happens and I all I get the default back button showing the title of the previous UIViewController on the stack:
- (UIBarButtonItem *)backBarButtonItem
{
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *backButtonImage = [UIImage imageNamed:#"back"];
[backButton setBackgroundImage:backButtonImage forState:UIControlStateNormal];
backButton.frame = CGRectMake(0, 0, 18, 27); // CGRectMake(0, 0, 23, 36);
UIBarButtonItem *backBarButton = [[UIBarButtonItem alloc] initWithCustomView:backButton] ;
[backBarButton setTarget:nil];
return backBarButton;
}
I also tried to use UIAppearance with this code:
UIImage *imgBack = [[UIImage imageNamed:#"back"] resizableImageWithCapInsets:UIEdgeInsetsMake(-6, 22, -6, 0)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:imgBack forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
But this just resulted in a distorted version of the back button that also still showed the title of the previous UIViewController .
So, my question is what is the easiest way to globally customize my back button such that it doesnt show the title of the previous UIViewController but rather only my custom image?
NOTE: I would like to avoid subclassing UINavigationController as well as having to set the back button explicitly within every UIViewController, actually the following code will work for this, if placed e.g. in viewDidLoad
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *backButtonImage = [UIImage imageNamed:#"back"];
[backButton setBackgroundImage:backButtonImage forState:UIControlStateNormal];
backButton.frame = CGRectMake(0, 0, 18, 27);
UIBarButtonItem *backBarButton = [[UIBarButtonItem alloc] initWithCustomView:backButton];
self.navigationItem.leftBarButtonItem = backBarButton;
So, what I am looking for is a truely global way to customize the back button exactly once.

Custom navigation bar back button with only image

I want to show custom navigation bar back button. I want to show only image on it. I want to use this button in whole app also dont want to create this button in each file. How can i??
Here is my code:
// Set the custom back button
UIImage *buttonImage = [UIImage imageNamed:#"back_arrow.png"];
//create the button and assign the image
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:buttonImage forState:UIControlStateNormal];
//set the frame of the button to the size of the image (see note below)
button.frame = CGRectMake(0, 0, buttonImage.size.width, buttonImage.size.height);
[button addTarget:self action:#selector(popViewControllerAnimated:) forControlEvents:UIControlEventTouchUpInside];
//create a UIBarButtonItem with the button as a custom view
UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.leftBarButtonItem = customBarItem;
but this is showing on current page only.
Another code:
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:[UIImage imageNamed:#"back_arrow.png"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
Using this code back button image is showing in whole app. But the text "Back" is also showing. How can i solve this problem.
Thanks in advance.
I've used a category in the past to do this.
Create a category on UIBarButtonItem called +projectButtons (or something).
Then you can have a function like...
+ (UIBarButtonItem)backArrowButtonWithTarget:(id)target action:(SEL)action
{
UIImage *buttonImage = [UIImage imageNamed:#"back_arrow.png"];
//create the button and assign the image
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:buttonImage forState:UIControlStateNormal];
//set the frame of the button to the size of the image (see note below)
button.frame = CGRectMake(0, 0, buttonImage.size.width, buttonImage.size.height);
[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
//create a UIBarButtonItem with the button as a custom view
UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];
return customBarItem;
}
Then add it to you navigation bar like so...
self.navigationItem.leftBarButtonItem = [UIBarButtonItem backArrowButtonWithTarget:self action:#selector(popViewControllerAnimated:)];
This means you only need one line of code to create it but you still get the customisation of the target and action in each VC that you use it in. If you decide to change the look of the button then it's all done in one place.

How to prevent animation of back button when switching views?

I cannot figure out how to disable the back-button animation that occurs in the navigation bar when switching from a tableview to a standard view (when a cell is selected). There is no obvious line of code that enabled animation to begin with. Here it is in gif-form:
The navigation buttons in the Facebook app do not animate, so it is possible.
It may be relevant to mention that I am using the ViewDeck library to create the Facebook-like tableView menu, i.e. swipe to the right to expose a table.
EDIT: solution is based on Hesham Abd-Elmegid's answer but modified to use a custom image...
UIImage *settingsImage = [UIImage imageNamed:#"back_button#2x.png"];
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
backButton.frame = CGRectMake(280.0, 10.0, 29.0, 29.0);
[backButton setBackgroundImage:settingsImage forState:UIControlStateNormal];
backButton.frame = CGRectMake(0, 0, 50, 30);
[backButton addTarget:self action:#selector(goBack) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
self.navigationItem.leftBarButtonItem = customBarItem;
If you set a custom UIBarButtonItem as a left navigation item (instead of standard back button item), it will fade instead of slide in, just like in Facebook's app. Just create a simple method that will replace back button functionality by calling popViewControllerAnimated: on the navigation controller in which your detail view controller is contained.
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:self action:#selector(goBack)] autorelease];
}
- (void)goBack
{
[self.navigationController popViewControllerAnimated:YES];
}
Note: UIBarButtonItem can also be set up with an image using initWithImage:style:target:action: method.
You could replace the back button with a custom UIButton. That way it won't animate on transition.
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTitle:#"Back" forState:UIControlStateNormal];
backButton.frame = CGRectMake(0, 0, 50, 30);
[backButton addTarget:self action:#selector(onBack) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
self.navigationItem.leftBarButtonItem = customBarItem;
[customBarItem release];
You will have to find a PNG for the arrow shape of the back button though.

Make image for back button fit the entire button

I'm developing an application where I use UINavigationController. I would like to set the image for a back button. I do this using the code below.
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"backArrow.png"] style:UIBarButtonItemStyleBordered target:nil action:nil];
self.navigationItem.backBarButtonItem = backButton;
But the image appears only in the middle of the back button. How can I set the image to span the whole back button?
For back button in UINavigationBar, if you add image it will show an image in center of the back buttobn only. You cannot add image in that too. So instead of doing that, hide your backbutton and add this code in your viewDidload Method to add a image for it and looks like what you need.
self.navigationItem.hidesBackButton = YES;
UIButton *button = [UIButton buttonWithType: UIButtonTypeCustom];
[button setBackgroundImage:[UIImage imageNamed:#"back_normal"] forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:#"back_pressed"] forState:UIControlStateSelected];
[button addTarget: nil action:#selector(popViewControllerAnimated:) forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake(0, 0, 50, 30);
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView: button];

Resources