Reputation: 3374
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?
Upvotes: 4
Views: 2702
Reputation: 11
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>
}
}
Upvotes: 1
Reputation: 2129
You can add the button into a ContainerView. Thus it will be on at all times. Food for thought....
Upvotes: 0
Reputation: 1930
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.
Upvotes: 1
Reputation: 3552
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
Upvotes: 12
Reputation: 6396
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.
Upvotes: 0
Reputation: 2584
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.
Upvotes: 0