Use Image for backBarButtonItem with NO TEXT - iphone

I'm simply trying to set the backBarButtonItem for my navigation controller to this image
instead of the Apple default arrow button whose title is the same as the previous view controller's title. The closest I've gotten so far is the above image stretched horizontally with the title still appearing overlaid. To get that, I used this code in my AppDelegate.
UIImage *backButtonImage = [UIImage imageNamed:#"back-button.png"];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage
forState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
How can I get rid of the title (and prevent the button from being stretched)?

When you use appearance, you are setting the background image of the back bar button items of your app. The fact that they have a background image has nothing to do with whether or not there is a title displayed on them. To use a custom bar button item instead of the default back item, look at this question.
In your case, you may want to not use appearance at all and instead create a bar button item as in the link above but use -initWithImage:style:target:action: instead of -initWithTitle:style:target:action:

you can set custom Image of BarbuttonItem like :-
- (void)viewDidLoad
{
UIImage* imageRight = [UIImage imageNamed:#"Home_btn.png"];
CGRect frameimgRight = CGRectMake(100, 100, 50, 30);
RightBtn = [[UIButton alloc] initWithFrame:frameimgRight];
[RightBtn setBackgroundImage:imageRight forState:UIControlStateNormal];
[RightBtn addTarget:self action:#selector(ActionhomeBtn)
forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *btnRight = [[UIBarButtonItem alloc]initWithCustomView:RightBtn];
self.navigationItem.leftBarButtonItem = btnRight;
[super viewDidLoad];
}
Look like:-
Hope its halp's you

I know this method works, and should be called in ViewDidLoad:
UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"back-button.png"] style:UIBarButtonItemStyleBordered target:nil action:#selector(methodName)];
which then has to be assigned to the nav bar:
item.rightBarButtonItem = backButtonItem;
and then pushed:
[self.navBar pushNavigationItem:item animated:NO];

Related

UIBarButtonItem:setBackgroundVerticalPositionAdjustment not working properly with custom button

I have the following code to customize the display of an UIBarButtonItem (locationButton):
UIButton *locationButtonAux = [UIButton buttonWithType:UIButtonTypeCustom];
[locationButtonAux setFrame:CGRectMake(0, 0, LOCATION_BUTTON_WIDTH, LOCATION_BUTTON_HEIGHT)];
[locationButtonAux setBackgroundImage:[UIImage imageNamed:#"location_button.png"] forState:UIControlStateNormal];
[locationButtonAux setBackgroundImage:[UIImage imageNamed:#"location_button.png"] forState:UIControlStateHighlighted];
[locationButtonAux addTarget:self action:#selector(userLocation) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *locationButton = [[UIBarButtonItem alloc] initWithCustomView:locationButtonAux];
UIBarButtonItem * item = [[UIBarButtonItem alloc] initWithTitle:#"title"
style:UIBarButtonItemStyleDone
target:nil action:#selector(someMssage)];
[locationButton setBackgroundVerticalPositionAdjustment:-20.0 forBarMetrics:UIBarMetricsDefault];
self.navigationItem.rightBarButtonItem = locationButton;
And I want to adjust the position of this button into the NavigationBar, because my NavigationBar is taller than normal (is customized using Appeareance).
I'm using the method setBackgroundVerticalPositionAdjustment, as you can see in the code, to do that. But is not working at all with my UIBarButtonItem, no matter what offset I put there, the button always appear close to the bottom of the bar (snapshot).
BUT, if I use a normal UIBarButtonItem with a normal style (the one I called button) I DO can see how the position of the button will be altered the offset of -20. Very strange... Any ideas?
Thank you!
Perhaps something like this would work for you:
UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 150, 30)]; //change this frame to counteract for your taller navbar
[rightView addSubview:locationButtonAux];
UIBarButtonItem *rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:rightView];
self.navigationItem.rightBarButtonItem = rightBarButtonItem;
Hope this helps
You need to put the button inside a blank view and position it within that blank view. Now make that view the custom view of the bar button item.
You really don't need a button here, since this is just an image and you are not using any of the button capabilities (you can attach a gesture recognizer to spot the tap). So here's a simple solution using an image view:
UIImageView *locationButtonAux =
[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"location_button.png"]];
UIView* v = [[UIView alloc] initWithFrame:locationButtonAux.frame];
[v addSubview:locationButtonAux];
CGRect f = locationButtonAux.frame;
f.origin.y -= 10;
locationButtonAux.frame = f;
UIBarButtonItem *locationButton = [[UIBarButtonItem alloc] initWithCustomView:v];
self.navigationItem.rightBarButtonItem = locationButton;
I've omitted the gesture recognizer part but you can easily see how to add it.

iOS 5: How to implement a custom (image) back button

I've done the tutorial at my blog, so I know how to make a stretchable button that can display the bottom (stack) viewcontroller's title. But what I was hoping to do is have icons (like a house for HOME) and no text and not resize.
Using my custom image and this code below, I get a stretched version (not wanted) with title over top (not wanted) and it does tint/highlight when clicked (is good);
UIImage *backButtonImage = [UIImage imageNamed:#"backButton_30.png"];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
screen shot 1
Now, I've searched on here and read all the similar questions which return old answers, and have strange results for me. Here is the code I tried;
UIImage *backButtonImage = [UIImage imageNamed:#"backButton_30.png"];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:backButtonImage style:UIBarButtonItemStyleBordered target:nil action:nil];
self.navigationItem.backBarButtonItem = backButton;
This method doesn't stretch out my custom image button (is good), nor does it show text (what I want) however there is still the original blue button under it (WTF), and my custom button doesn't tint when clicked, only the blue button under it does!
screen shot 2
Please help, what am I missing?
*UPDATE
I've fixed it up a bit by using a resizable image. This forces it not to 'stretch'
UIImage *backButtonHomeImage = [[UIImage imageNamed:#"backButtonHomeWhite_30.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonHomeImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
To fix the title showing up on the button I had to do
self.title =#" ";
Now this is a bit of a dirty fix but it seems to be working. The only problem left now is that I want a different back button on different views, and this method is causing some trouble; the last view that sets the button over-rides all other views. So in the end, depending on how you navigate through the app, returning to a previous view has the wrong back button and it never resets to the correct one.
UPDATE 2: POTENTIAL IDEA:
Would the following be a reasonable solution, or is it a hack that is liable to break something?
Hiding the default back button, like so,
[self.navigationItem setHidesBackButton:YES animated:NO];
...and then using a custom UIBarButtonItem, with a button in the style I actually want placed in the location of the back button, that sends a popViewControllerAnimated: message to the UINavigationController when tapped.
If you know of a more robust solution please do share, thank you.
Assuming that your current solution
UIImage *backButtonHomeImage = [[UIImage imageNamed:#"backButtonHomeWhite_30.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonHomeImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
is acceptable to you, so the only problem left is how to update that button appeareance when you go back and forth between your views, an approach that could work is executing the code above in each of your controllers' viewWillAppear: method:
- (void)viewWillAppear:(BOOL)animated {
UIImage *backButtonHomeImage = [[UIImage imageNamed:#"backButtonHomeWhite_30.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonHomeImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
}
If you are not satisfied with your current approach to having a custom UIBarButtonItem, the way to go is initializing your bar button item with initWithCustomView:. In this case, you can specify, e.g., a UIImageView with the image you like and it should work:
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:[UIImageView ...]];
Hope this helps.
For iOS 5+ use [[UIBarButtonItem appearance] setBackButtonBackgroundImage:[UIImage imageNamed:#"someimage.png"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault].
Some code i used in a project:
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *btnImg = [UIImage imageNamed:#"ButtonRetourInactive"];
[btn setImage:btnImg forState:UIControlStateNormal];
btn.frame = CGRectMake(0, 0, btnImg.size.width, btnImg.size.height);
[btn addTarget:self action:#selector(goBack:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:btn] autorelease];
Note, this works on iOS 4 and 3 aswell.
if You are using story boards , its too easy . take a round rectangular button and place it on the navigation bar . then double click the button( on selecting,at first, it just shows attributes of bar button , but by selecting twice , you can change all its properties as if you are customizing a regular UI button) .
UIAppearance is no use in this case.
I tried to use:
- [UIBarButtonItem initWithCustomView:].
The view here you can add your background image and title, whatever you want.

are customViews for UIBarButtonItems ignored for the leftBarButtonItem

From the documentation, I see this for the backBarButtonItem:
When this property is nil, the navigation item uses the value in its
title (page 10) property to create an appropriate back button. If you
want to specify a custom image or title for the back button, you can
assign a custom bar button item (with your custom title or image) to
this property instead. When configuring your bar button item, do not
assign a custom view to it; the navigation item ignores custom views
in the back bar button anyway.
I didn't know if this was the same for leftBarButtonItem? Basically I have this code:
UIButton *homeButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
UIImage *homeImage = [UIImage imageNamed:#"icon_house.png"];
[homeButton setImage:homeImage forState:UIControlStateNormal];
[homeButton addTarget:self action:#selector(homePressed:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *homeBBI = [[UIBarButtonItem alloc] initWithCustomView:homeButton];
Prior to iOS 5, I put this in a UIToolBar and it showed up fine. Now I want to put this as the leftBarButtonItem, to the right of the UINavigationController's backButton. When I set it, it does not show up at all. There is no image. However, when I create some button like this:
UIBarButtonItem *hButton = [[UIBarButtonItem alloc] initWithTitle:#"home" style:UIBarButtonItemStylePlain target:self action:#selector(homePressed:)];
and set it as the leftBarButtonItem, it shows up. I didn't know how I could get my custom icon for my home button without the borders. When I use:
UIBarButtonItem *hButton2 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"icon_house.png"] style:UIBarButtonItemStylePlain target:self action:#selector(homePressed:)];
I get a border around my house_icon that i do not want. Thanks.
try this
UIButton *TastoVersamento = [UIButton buttonWithType:UIButtonTypeCustom];
[TastoVersamento setImage:[UIImage imageNamed:#"Versamento.png"] forState:UIControlStateNormal];
[TastoVersamento addTarget:self action:#selector(Click_Versamento:) forControlEvents:UIControlEventTouchUpInside];
[TastoVersamento setFrame:CGRectMake(0, 0, 40, 40)];
[[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] initWithCustomView:TastoVersamento] autorelease]];
backBarButtonItem and leftBarButtonItem are different. backBarButtonItem is the default if no leftBarButtonItem is given. It will also show up even if leftBarButtonItem is set if leftItemsSupplementBackButton is YES.
In your first example, you could try [homeButton sizeToFit]. I think the frame may not be getting set correctly.
But as to your last comment, I think you won't be succesful in removing the border from navigation item buttons. I'm pretty sure they're hard coded. In fact, if you add a button that has a border, you'll get two, one from the button and one from the navigation item.

UIBarButtonItem appearance and setBackButtonBackgroundImage

I change my back button when pushing a new viewcontroller in my navigationcontroller. But it doesnt look nice and its stretched. Also, how can I remove the "News" title in my back button?
here's my code. see the image
and the code is
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:[UIImage imageNamed:#"back_button.png"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
I want to achieve something like this http://i228.photobucket.com/albums/ee262/romano2717/photo4.png
Use the following code to put the image in position.
int imageSize = 20; //REPLACE WITH YOUR IMAGE WIDTH
UIImage *barBackBtnImg = [[UIImage imageNamed:#"NavBackButton"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, imageSize, 0, 0)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:barBackBtnImg
forState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
You can use resizableImageWithCapInsets to specify which pixels should not be stretched. If you put your image-width in there it won't stretch your image.
You don't have to put it in the .m file btw. (You could use the appDelegate.m file) just make sure it get's called before the NavigationBar is drawn.
Unless I'm missing something, you have to create the UIBarButtonItem in code to remove or change the title, so it would only apply to the view controllers you put the code in:
UIBarButtonItem *myBackButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"back_button.png"] style:UIBarButtonItemStyleBordered target:nil action:nil];
self.navigationItem.backBarButtonItem = myBackButton;
[myBackButton release];
The reason why the code you posted works that way is because it only sets the background and the documentation does state that:
For good results, backgroundImage must be a stretchable image.
You can create custom Button and add it as a bar button to remove the stretch. or you can get graphics of back button size.
to remove the title of the button you have to set self.title = ""; in viewWillDisappear method and set title again when in viewWillAppear method.
hope this will solve your issue.
Use youparentViewController.title = #" ";
I did have the same problem with the title
Below code will Remove Title from the Back button.
UIBarButtonItem *theBackButton = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStylePlain target:self action:#selector(yourAction)];
[[UIBarButtonItem appearance] setBackBarButtonItem:theBackButton];
[theBackButton release];

Image on Navigation Bar Back Button

In our application I use Left and right button on navigation bar.
I want a image on back (left)button.If i use segment for that then
necessary to define a action for back button.
Please advice me for any method.
Yeah, if you use a Bar Button item you can go to Bar Button Item Attributes in Interface Builder and there should an Image option you can select.
The easiest way we found to replace the back button with our own goes like this.
Add a back button in the nib file outside your view. customize it as you wish.
connect it as an IBOutlet. Let's call it btnBack.
in ViewDidLoad do this:
UIBarButtonItem *back = [[UIBarButtonItem alloc] initWithCustomView:btnBack];
[self.navigationItem setLeftBarButtonItem:back animated:YES];
connect an action to your backBtn like this:
- (IBAction)Back:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}
And thats it you got yourself a customized back button :)
You can do it by subclassing UINavigationBar, then create a method like this :
+ (UIBarButtonItem *)barButtonWithImage:(NSString *)imageName target:(id)target action:(SEL)action {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
UIImage *titleImage = [UIImage imageNamed:imageName];
[button setImage:titleImage forState:UIControlStateNormal];
[button sizeToFit];
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:button];
return item;
}
And then add it to your navigation bar like this :
[self.navigationItem setLeftBarButtonItem:[TFNavigationBar barButtonWithImage:#"rp_settings.png" target:self action:#selector(showSettings)]];
p.s: I prefer to use singletons, that's why that it is.
If you want to simply replace your back button with an image through out your app..
[[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:#"back_button"]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:#"back_button"]];
Or for specific navigation bars specify your navBar instead of '[UINavigationBar appearance]'. This works perfectly.