Reputation: 1949
I'm trying to change navigation bar's right item globally. So I created parent class like this:
@implementation ParentViewController
...
- (void)loadView {
[super loadView];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"send"]];
self.navigationController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:sendImageView];
}
...
@end
And I have two ViewController
classes named A
and B
that inherits from ParentViewController
. Both of them has
- (void)loadView {
[super loadView];
}
First instance of A comes out and performs
B *vc = [[B alloc] init];
[self.navigationController pushViewController:vc animated:YES];
The problem is that right bar button item appears only on A but not on B. I thought parent class's loadView
getting called will do the trick but is not. How do I change that button globally?
I'm not using xib. So loadView always gets called.
Upvotes: 0
Views: 1406
Reputation: 164
I recently wrote a blog post about this issue: http://www.codebestowed.com/ios-shared-barbuttonitems/
The basic idea is to subclass UINavigationController, give it a BarButtonItem property (self.myButton in the code below) and add code similar to:
- (void)viewDidLoad
{
[super viewDidLoad];
self.delegate = self;
}
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (!viewController.navigationItem.rightBarButtonItem) {
viewController.navigationItem.rightBarButtonItem = self.myButton;
}
}
For those interested, the blog post details how you can set this up further in InterfaceBuilder, which requires a bit of a hack (too much to go into in this answer).
Upvotes: 0
Reputation: 1949
I think I have found some way to solve it. It changes right item as plain image and sets left item as back button with the title of "Back".
@implementation ParentViewController
- (void)loadView {
[super loadView];
UIImageView *sendImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"send"]];
sendImageView.frame = CGRectMake(0, 0, 44, 44);
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:sendImageView];
//don't need the original back button
self.navigationItem.hidesBackButton = YES;
self.navigationItem.leftBarButtonItem = nil;
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:self action:@selector(back)];
[self.navigationItem.leftBarButtonItem configureFlatButtonWithColor:[UIColor whiteColor] highlightedColor:[UIColor lightGrayColor] cornerRadius:5];
self.navigationItem.leftBarButtonItem.title = @"Back";
[self.navigationItem.leftBarButtonItem
setTitleTextAttributes:@{
UITextAttributeTextColor: [UIColor colorFromHexCode:@"53a4db"],
UITextAttributeTextShadowColor: [UIColor clearColor],
UITextAttributeFont: [UIFont fontWithName:@"ChalkboardSE-Bold" size:15]
} forState:UIControlStateNormal];
}
-(void)back {
[self.navigationController popToRootViewControllerAnimated:YES];
}
@end
So if child class don't need to have back button it can self.navigationItem.leftBarButtonItem = nil;
Upvotes: 0
Reputation: 119031
loadView
won't be called if the view controller has an associated XIB as that will be used to load the view.
You might want to consider acting as the delegate
of UINavigationController
to handle this stuff and implementing navigationController:willShowViewController:animated:
. You can then directly interrogate the new viewController
to decide if you should do anything and, if required, you can change its navigationItem
.
Upvotes: 1