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.
Related
I'm having problems to create an custom nav bar like the Uber app.
I'm setting my button background image to:
UIImage *button44 = [[UIImage imageNamed:#"navButtonAdd"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UIBarButtonItem appearance] setBackgroundImage:button44 forState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
But If I remove the text from the button on the xcode interface it disappear the image as well and also there is a padding on the right that starts repeating my image again.
Does anyone know how I could fix it?
This is the image I'm trying to use as a button
Thanks in advance
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"button"]]];
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"uberbar.png"] forBarMetrics:UIBarMetricsDefault];
If I'm not mistaken you need a custom view on the UIBarButtonItem. So you could get the appearance proxy, set the image for the controller, or instead customize the image directly. That padding is a matter of photoshopping the graphic and set its dimensions correctly.
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];
A designer asked me to add pagination to a UINavigation bar in a project with its target building for ios4.3+.
I know you can add two buttons to the right side of a Navigation bar as explained here in this blog : enter link description here
But to get the appearance requested to by the designer
Do I need to add images to my button or is this some kind of native control(Special UISegmentedControl?) I haven't seen before? Or Just 2 custom buttons with background images.
Thanks,
-Code
I implemented the same function with a segmented control and without defining custom buttons with images.Instead of adding images for arrows i used the the corresponding Unicode chars and instantiated the segmented control with them.
UISegmentedControl *toggleSegmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"\u25B2",#"\u25BC",nil]];
UIBarButtonItem *toggleSegmentedControlBarItem = [[UIBarButtonItem alloc] initWithCustomView:toggleSegmentedControl];
self.navigationItem.leftBarButtonItem = toggleSegmentedControlBarItem;
Then your leftBarButtonItem is replaced by the segmented control.
If I undestand, you want put a image in each UIBarButtonItem and setting button status (when is clicked or normal condition). If yes, you can try this code
`UIImage *buttonImageNormal = [UIImage imageNamed:#"image.png"];
UIImage *buttonImagePressed = [UIImage imageNamed:#"imagepressed.png"];
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setImage:buttonImage forState:UIControlStateNormal];
[myButton setImage:buttonImage forState: UIControlStateHighlighted];
UIBarButtonItem aBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:myButton];
// Create and Set the Target and Action for aButton
[myButton addTarget:self action:#selector(myButtonClicked:) forControlEvents:UIControlEventTouchUpInside];`
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.
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];