Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 802
RobDigital Avatar asked May 25 '12 15:05

RobDigital


People also ask

How do you implement a Back button in Swift?

To do this, Ctrl-click and drag from the button to the destination view controller and select "Show Detail". Show activity on this post. I had the same problem, even when on the storyboard the back button was visible at design time.


2 Answers

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.

like image 170
sergio Avatar answered Sep 28 '22 05:09

sergio


For iOS 5+ use [[UIBarButtonItem appearance] setBackButtonBackgroundImage:[UIImage imageNamed:@"someimage.png"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault].

like image 35
Andrew Theis Avatar answered Sep 28 '22 05:09

Andrew Theis