Adding UIBarButtonItem to all Navigation View Controllers inside a UITabBarController programmatically - ios

The structure is as follows:
View
Tab Bar Controller
Navigation Controller
View Controller
Navigation Controller
View Controller
Navigation Controller
View Controller
Navigation Controller
View Controller
Navigation Controller
View Controller
Navigation Controller
View Controller
The above controllers have been initialised in interface builder.
What I'm trying to do is add a right UIBarButtonItem to each navigation controller but not having any success.
Here's what I've tried:
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor];
self.view.opaque = NO;
self.tabBarController.view.frame = self.view.bounds;
NSArray *currentViewControllers = self.tabBarController.viewControllers;
NSMutableArray *updatedViewControllers = [NSMutableArray array];
for (int i=0; i<currentViewControllers.count; i++) {
UINavigationController *tempNav = [[UINavigationController alloc]init];
tempNav = [currentViewControllers objectAtIndex:i];
UIBarButtonItem *dismissButton = [[UIBarButtonItem alloc]
initWithTitle:#"Done"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(dismissLibraryBrowser)];
tempNav.navigationItem.rightBarButtonItem = dismissButton;
[updatedViewControllers addObject:tempNav];
[dismissButton release];
[tempNav release];
NSLog(#"Added controller number %d",i);
}
self.tabBarController.viewControllers = [NSArray arrayWithArray:updatedViewControllers];
[self.view addSubview:tabBarController.view];
}
The code executes without any errors, but the button doesn't appear. I'm sure I've misunderstood something here. Would appreciate some guidance.

You are over complicating things slightly with recreating viewControllers and temporary arrays. You just need to manipulate the objects loaded from the nib
[self.tabBarController.viewControllers enumerateObjectsUsingBlock:^(UINavigationController *navigationController, NSUInteger idx, BOOL *stop) {
UIViewController *rootViewController = [navigationController.viewControllers objectAtIndex:0];
UIBarButtonItem *rightBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(dismissLibraryBrowser)];
rootViewController.navigationItem.rightBarButtonItem = rightBarButtonItem;
}];
As for the structure of your app - the docs for UITabBarController say
When deploying a tab bar interface, you must install this view as the root of your window. Unlike other view controllers, a tab bar interface should never be installed as a child of another view controller.
So I would suggest having a look at restructuring some stuff, if you need it only occasionally why not consider presenting it modally?

Related

Easier way to implement navigation bar item with tab bar controller?

I have a tab bar controller as my root view with 5 navigation controllers (one for each tab). The navigation bar in each tab will have a button that has the same functionality across all tabs. Is there an easier way to add this button (and respond to selection) than copy/pasting it into each navigation controller?
EDIT:
In my custom navigation controller's child view controller, I have:
- (void)viewDidLoad
{
[super viewDidLoad];
...
CustomNavigationController *navController = [self.storyboard instantiateViewControllerWithIdentifier:#"HomeNavigationController"];
[navController addNotificationsButton:YES searchButton:NO];
}
and in the custom navigation controller I have:
-(void)addNotificationsButton:(BOOL)notifications searchButton:(BOOL)search { //Choose which bar button items to add
NSMutableArray *barItems = [[NSMutableArray alloc]init];
if (notifications) {
//Create button and add to array
UIImage *notificationsImage = [UIImage imageNamed:#"first"];
UIBarButtonItem *notificationsButton = [[UIBarButtonItem alloc]initWithImage:notificationsImage landscapeImagePhone:notificationsImage style:UIBarButtonItemStylePlain target:self action:#selector(notificationsTap:)];
[barItems addObject:notificationsButton];
}
if (search) {
//Create button and add to array
UIBarButtonItem *searchButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:#selector(searchTap:)];
[barItems addObject:searchButton];
}
[self.navigationItem setRightBarButtonItems:barItems];
}
But I just get an empty navigation bar when the child view controller loads. Any ideas?
EDIT 2:
I just had to add an argument for the view controller who's navigation bar I wanted to add buttons to. Here is the final implementation...
for CustomViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
...
CustomNavigationController *navController = [self.storyboard instantiateViewControllerWithIdentifier:#"HomeNavigationController"];
[navController addNotificationsButton:YES searchButton:NO forViewController:self];
}
For CustomNavigationController.m
-(void)addNotificationsButton:(BOOL)notifications searchButton:(BOOL)search forViewController:(UIViewController*)vc { //Choose which bar button items to add
NSMutableArray *barItems = [[NSMutableArray alloc]init];
if (notifications) {
//Create button and add to array
UIImage *notificationsImage = [UIImage imageNamed:#"first"];
UIBarButtonItem *notificationsButton = [[UIBarButtonItem alloc]initWithImage:notificationsImage landscapeImagePhone:notificationsImage style:UIBarButtonItemStylePlain target:self action:#selector(notificationsTap:)];
[barItems addObject:notificationsButton];
}
if (search) {
//Create button and add to array
UIBarButtonItem *searchButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:#selector(searchTap:)];
[barItems addObject:searchButton];
}
vc.navigationItem.rightBarButtonItems = barItems;
}
You need to create a subclass of UINavigationController,
configure it as you want (so with your button),
and set that as class of your 5 Navigation Controller.
Obviously i can't write here all your apps, but the important is that you have a way.
If you are a developer at the first times, i encourage you to study about subclassing etc.
Subclass navigation bar and add button as part of subclass. Now you can use 5 instances of the subclass instead of the 5 base navigation bars and cut out the repeated work of adding the buttons.

Back button pressed, losing my custom UIToolBar when i pop the view controller off the stack

I hope everyone is having a great day so far.
I'm running into a problem with my app that I need some help figuring out. I have a view controller (lets call "A") with a custom toolbar which works nicely.
When I push a view controller (lets call it "locationsController") from view controller "A" ...
[self.navigationController pushViewController:self.locationsController animated:YES];
...and I press the back button on the locationsController which closes like this...
[self.navigationController popViewControllerAnimated:YES];
I lose my custom toolbar in view controller "A" when locationController is popped. How do I fix it so I can intercept and call my buildtoolbar method?
Also, the locationsController can be pushed/popped from one other view controller so I'll need to determine which view controller is popping locationsController and either fire the buildtoolbar method or do nothing since the other view controller doesn't have a toolbar.
view controller "A" is a XIB while locationsController is defined in the storyboard.
the XIB does not Have a toolbar in the view/layout thingy.
toolbar code called from viewDidLoad [self buildToolbar]...
-(void) buildToolbar{
blah blah blah
self.navigationController.toolbarHidden = NO;
UIBarButtonItem *flexableItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *refresh = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:#selector(refresh:)];
UIBarButtonItem *comments = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"Comments-selected.png"] style:UIBarButtonItemStyleDone target:self action:#selector(cameraButtonTapped:)];
UIBarButtonItem *pin = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"Pin-straight_60wide.png"] style:UIBarButtonItemStyleDone target:self action:#selector(pinBarButtonItemPressed:)];
NSArray *items = [NSArray arrayWithObjects:customBarButtonItem_right, flexableItem, comments, flexableItem, pin, flexableItem, refresh, nil];
// [self.navigationController.toolbar setItems:items animated:YES];
self.toolbarItems = items;
}
Thanks in advance!
I moved my call to toolbarSetup from viewDidLoad to viewWillAppear. Apparently the 2nd VC's viewDidLoad doesn't fire when the top most VC is popped off the stack.
viewWillAppear fires followed by viewDidAppear, etc....

how to add tabbarcontroller in a navigation controller

I need to have a tabbar kind of view in a view controller(say view controller 3) which is in navigation stack and will be pushed by another view controller (say view controller 2).
I added tool bar to view controller 3 with many buttons. But managing and switching between views seems difficult.
How can i add a tabbar controller in the middle of navigation stack.
please help me out.
You cnt create tabbar in the middle of view controllers, you can create tab bar structure using custom segment controller. check the link below for creating custom segment controller.
https://www.cocoacontrols.com/search?q=segment
You cannot add TabBar there - tabBar is only designed to be at the bottom.
You have to create your own ViewController and add it as subView for navigationViewController and implement whole switching methods.
There has been some discussion about this design in related questions.
The way I understand your question it's definitely possible though. I am pushing a UITabBarController onto a UIViewController that is embedded in a UINavigationController. I did everything in the interfacebuilder except for the push which I implemented programmatically.
So in ViewController.m I added an action to a button:
- (IBAction)searchForPlacesButtonPressed:(id)sender {
TabBarController *tc = [[self storyboard] instantiateViewControllerWithIdentifier:#"TabBarController"];
tc.title = #"Orte";
tc.tabBar.selectedImageTintColor = [UIColor colorWithRed:(28.0f/255.0f) green:(100.0f/255.0f) blue:(52.0f/255.0f) alpha:1.0f];
UIBarButtonItem * logo = [[UIBarButtonItem alloc] initWithCustomView:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"icon_xyz"]]];
tc.navigationItem.rightBarButtonItem = logo;
Places *d = [[Places alloc] init];
for (UIViewController *vc in tc.viewControllers) {
if ([vc isKindOfClass:[MapViewController class]]) {
((MapViewController *)vc).dataHandler = d;
((MapViewController *)vc).mapViewDelegate = d;
vc.tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Karte" image:[UIImage imageNamed:#"map"] tag:0];
}
else if ([vc isKindOfClass:[TableViewController class]]) {
((TableViewController *)vc).dataHandler = d;
vc.tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Liste" image:[UIImage imageNamed:#"eye"] tag:1];
}
}
[self.navigationController pushViewController:tc animated:YES];
}
Using the tabs at the bottom you can switch between viewing the places on a map and listed in a table.

How to switch views from barbuttonitem?

I have an overlay in which I've created a toolbar containing a done button.
The name of the selector for done button is doneButtonPressed.
Now when I click done button, how do I get a new nib view? Let's us assume I created a nib named TestViewController.
-(void)doneButtonPressed {
//What goes here?
}
If you want to instantiate a UIViewController from a nib you can use the following line of code:
UIViewController *viewControllerName = [[UIViewController alloc] initWithNibName:(NSString *) bundle:(NSBundle *)];
Then you can present the view modally with:
[self presentModalViewController:(UIViewController *) animated:(BOOL)];
Now if you are using a storyboard, then you could just instantiate a view controller from a storyboard object.
Not sure if this is what you are looking for, but you could turn your view into a "container view". To do that you will need to create subviews and then just switch them out. I did this when I wanted a menu to control a different view.
[self.view insertSubview:(view you want to insert) atIndex:0];
Then when you want to switch it out:
[[[self.view subviews] objectAtIndex:0] removeFromSuperview];
[self.view insertSubview:(view you want to replace with) atIndex:0];
EDITED
UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(doneButtonPressed:)];
- (void)doneButtonPressed {
SkipQViewController *skipQ = [[SkipQViewController alloc] initWithNibName:#"Name" bundle:bundleName];
[self presentModalViewController:skipQ animated:YES];
}
If that does not work try using: SkipQViewController *skipQ = [[SkipQViewController alloc] init]; to instantiate your view controller.
-EDIT-
Instantiate the view controller as such: SkipQViewController *skipQ = (SkipQViewController *)[[UIViewController alloc] initWithNibName:#"sqvc" bundle:nil];

Button not being added on navigation controller

- (void)viewDidLoad
{
[super viewDidLoad];
ac = [[AddContacts alloc]init];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:ac];
[self.view addSubview:navigationController.view];
UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:#"Show" style:UIBarButtonItemStylePlain target:self action:#selector(refreshPropertyList:)];
self.navigationController.navigationItem.rightBarButtonItem = anotherButton;
}
Why is my button not being added on the navigation controller?
The UIBarButtonItems are not controlled by the navigation controller, but by each of the view controllers it contains - each UIViewController can have different buttons. Try:
ac = [[AddContacts alloc]init];
UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:#"Show" style:UIBarButtonItemStylePlain target:self action:#selector(refreshPropertyList:)];
ac.navigationItem.rightBarButtonItem = anotherButton;
Then initialize the UINavigationController as you have been doing.
There are a few things here that could be causing issues.
Probably what the main issue is this line:
self.navigationController.navigationItem.rightBarButtonItem = anotherButton;
I am pretty sure that what you want to be setting is the right bar button item on the ac view controller's navigation item.
ac.navigationItem.rightBarButtonItem = anotherButton
A few other things though:
Don't have two letter variable names. "ac" is very ambiguous, "addContacts" would provide more information, "addContactsViewController" would provide even more
Are you implementing your own navigationController property in a UIViewController subclass? This is not recommended as it is overriding the navigationController property that UIViewController already has. Give it a different name.
Is the -viewDidLoad method on the parent view controller the place to be assigning the right bar button of your AddContacts object? Consider instead putting the code to set the bar button in the implementation of AddContacts instead.

Resources