Make a custom back button for UINavigationController
Asked Answered
C

3

5

I'm developping an app for iOS 4.2+. I subclassed my UINavigationController to insert two UIImageView and make the navigation bar look custom. Everything is working great but I have a little problem. I created custom UIBarButtonItem and inside my view controllers i put them with :

self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:backButton];

It works too but the problem is that to make this work I need to call it from:

 - (void)viewDidAppear:(BOOL)animated ;

So it only appears after the animation and I can see the non customized button 1 second before the customized one replace it.

(I tried with viewWillAppear but then nothing append in navigationbar)

I would like to know if you have a solution that could correct this problem.

PS: I never use IB, everything is made programmatically.

Thanks from France !

EDIT 1: here is the code that didn't show anything for viewWillAppear:

- (void)viewWillAppear:(BOOL)animated  {
    [self setTitle:@"Jeu"];

    //Bouton testflight
    TIFButton *testFeedbackButton = [[TIFButton alloc]init];
    [testFeedbackButton setTitle: @"Envoyer un Feedback" forState:UIControlStateNormal];
    [testFeedbackButton addTarget:self action:@selector(launchFeedback) forControlEvents:UIControlEventTouchUpInside];

    UIBarButtonItem *testFeedback = [[UIBarButtonItem alloc] initWithCustomView:testFeedbackButton];

    self.navigationItem.rightBarButtonItem = testFeedback;  

    TIFBackButton *backButton = [[TIFBackButton alloc]init];
    [backButton setTitle: @"Retour" forState:UIControlStateNormal];
    [backButton addTarget:self action:@selector(popToPrecedentViewController) forControlEvents:UIControlEventTouchUpInside];

    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:backButton];
}
Contamination answered 15/2, 2012 at 20:5 Comment(2)
It should work with viewWillAppear, but your backButton view needs to be instantiated / created before you assign self.navigationItem.leftBarButtonItem.Swallow
Why do you need to call it from viewDidAppear? Why doesnt't it work from viewDidLoad?Posthorse
S
19

Let's say you have two ViewControllers, A and B, you're pushing B onto the stack when A is topmost, and you want to customize the back button that shows up when B is on top.

Typically, the way to do this is to set ViewController A's navigationItem.backBarButtonItem.

Instead, what you're doing is to give ViewController B a custom button on the left side of the navbar by setting its navigationItem.leftBarButtonItem.

You've implemented that approach fine, except that even if you don't set ViewController A's navigationItem.backBarButtonItem, by default you still get a default back button as well. So that button is probably showing up on top of your custom back button.

If you set ViewController B's navigationItem.hidesBackButton = YES then you shouldn't have any problem.

And in the future, when you implement custom back buttons, you should do it by setting navigationItem.backBarButtonItem instead of navigationItem.leftBarButtonItem. The one adjustment you'll have to make is that with this approach, for example you would use ViewController A's navigationItem to change the back button that shows up when ViewController B is on top.

Sheryl answered 15/2, 2012 at 21:17 Comment(3)
Thanks, I solved the problem. You're right on everything you said, it was really helpful but I found the error that blocked the UIBarButton to show up. In effect, the UIImageView I added in the subclass was "hiding" the button when they were called with viewWillAppear. So two problems, each one solved. Again, thank you !Contamination
The problem with this approach is that you can't set the back button to a custom view. The best you can do is change the background image. If you want more control over how the button looks, it seems that you have to go with setting leftBarButtonItem on ViewController B as the OP has done.Intake
What worked for me was B.navigationItem.hidesBackButton = YES and B.navigationItem.leftBarButtonItem = <my custom button>.Avoidance
R
4
UIBarButtonItem *backButton = [UIBarButtonItem new];

[backButton setTitle:@"Back"];

[[self navigationItem] setBackBarButtonItem:backButton];

This code you have to mentioned in previous view controller then only it default back button came in next view controller.

Enjoy!!!

Robby answered 19/12, 2013 at 12:38 Comment(0)
M
1

I've come up with a somewhat universal solution: https://mcmap.net/q/669296/-iphone-custom-uibarbuttonitem-for-back-button It involves a category on UIViewController and requires minimal code to have an image back button on all your screens.

Malpighiaceous answered 30/5, 2013 at 8:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.