Question

I Have UINavigationController in my app, I want to have a right UIBarButtonItem to be shown in all navigation bar that appear in my application. this button will load menu, so I don't want to add this button in every navigation bar manually, also as the function is loading menu, I don't want to copy/past action for this button.

is there any way to handle this in ViewController.h and .m ?

so the button act as a universal bar button item?

Was it helpful?

Solution

What you can do is subclass the navigation controller. Here is an example

@interface NavigationController : UINavigationController
@end

@interface NavigationController () <UINavigationBarDelegate>
@end

@implementation NavigationController

- (void)viewDidLoad
{
    [super viewDidLoad];
    for (UIViewController* viewController in self.viewControllers){
        // You need to do this because the push is not called if you created this controller as part of the storyboard
        [self addButton:viewController.navigationItem];         
    }
}

-(void) pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
    [self addButton:viewController.navigationItem];
    [super pushViewController:viewController animated:animated];
}

-(void) addButton:(UINavigationItem *)item{
    if (item.rightBarButtonItem == nil){
        item.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(action:)];
    }
}

-(void) action:(UIBarButtonItem*) button{

}

@end

OTHER TIPS

This cannot be done unless you use a custom view to look like NavigationBar. By default, NavigationController clears all bar button items when a ViewController is pushed or popped. So for every ViewController, you need to create UIBarButtonItem every time in function

- (void)viewWillAppear:(BOOL)animated

or use can subclass UINavigationController and do as @rp90 answer.

You can add a button that appears in your UINavigationController by adding it in the UINavigationController's delegate - in this example, a singleton helper class.

Swift 3:

class NavHelper: UINavigationControllerDelegate {
    static let shared = NavHelper()

    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        let barButtonItem = UIBarButtonItem(image: <yourButtonImage>, style: .plain, target: NavHelper.shared, action: #selector(NavDelegate.handleButton(_:)))
        viewController.navigationItem.rightBarButtonItem = barButtonItem
    }

    func handleButton(_ sender: UIBarButtomItem) {
        <yourCode>
    }
}

Another option is to make your own navigation bar view as a part of the UIViewController. You can turn off Apple's and build your own. We did this to provide our own controls easier. The only thing you lose is the easy translucency under iOS 7. A lot of apps do this for the same reason we did.

You can create a new class that inherits from UIViewController and in the viewDidLoad method, create a UIBarButtonItem and add it to the navigationItem as a left/right bar item. Let's say this class is called CustomBarViewController:

UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithTitle:@"hi" style:UIBarButtonItemStylePlain target:self action:@selector(doSomething:)];
[self.navigationItem setRightBarButtonItem:barItem];

In your existing view controllers, instead of having them inherit from UIViewController in the .h file, you can have them use CustomBarViewController instead:

@interface MyExistingViewController : CustomBarViewController

You can then put actions into the doSomething: method, or have it pass notifications to your existing view controllers.

You can add the button into a ContainerView. Thus it will be on at all times. Food for thought....

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top