How do I set up a Tab Bar Controller within an existing Navigation Controller? - uinavigationcontroller

I'm pretty new to iOS. I'm building an app and am running into an issue. I have a navigation controller with a table view controller atop its stack. When I select a row in that table view controller, what I'd like to see is a collection view with the following:
The nav bar with the name that appears on the selected cell as the navigation item title.
A collection view as the main interface
a tab bar with the collection view, and an imagePickerController
Here's what my code looks like:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NewTabBarController *tbc = [[NewTabBarController alloc] init];
UIImagePickerController *takeAPicture = [[UIImagePickerController alloc] init];
UITabBarItem *tabItem = [takeAPicture tabBarItem];
[tabItem setImage:[UIImage imageWithContentsOfFile:#"CameraIcon.jpg"]];
[tabItem setTitle:#"Take a photo!"];
UICollectionViewFlowLayout *photoFlow = [[UICollectionViewFlowLayout alloc] init];
PhotoCollectionViewController *photoHub = [[PhotoCollectionViewController alloc] initWithCollectionViewLayout:photoFlow];
[tbc setViewControllers:[NSArray arrayWithObjects:photoHub, takeAPicture, nil]];
NSArray *items = [[items accessor] allItems];
Item *item = [items objectAtIndex:[indexPath row]];
[photoHub setItem:item];
[photoHub useLayoutToLayoutNavigationTransitions];
[[self navigationController] pushViewController:tbc animated:YES];
}
Then in my PhotoCollectionViewController implementation I have:
#syntesize item;
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationItem *itemHeader = [self navigationItem];
[itemHeader setTitle:[item itemName]];
UITabBarItem *tabItem = [self tabBarItem];
[tabItem setImage:[UIImage imageWithContentsOfFile:#"itemImage.jpg"]];
[tabItem setTitle:[NSString stringWithFormat:#"Photos of %#", [item itemName]]];
}
My problem is that when I select the cell, The collection view loads, and I can see the cells I have set up in the collection view, but the nav bar item has no title, and the tab bar item has "Photos of (null)" and no image. The "Take a photo!" text appears, but the image does not.
Do you guys have any idea how I can restructure this to make everything flow correctly. I must be doing something wrong in the way I'm utilizing tab and nav controllers.I don't want there to be any tabs until this stage in the app, which is 3 or 4 VCs in already. Should I be using a tab bar controller from the App Delegate onward?

The problem here is that you are pushing tab bar controller onto a navigation controller stack. The view controllers of a tab bar will have a navigation item, but their navigation items aren't shown when the view controller is on screen. Instead, the tab bar controller's navigation item is on screen.
You could use self.tabBarController.navigationItem, but then each view controller will have to modify the navigation item every time it's brought on/off screen, which is really messy.
If you're going to use a UITabBarController, I would recommend either presenting it modally, or having it be the root view controller on your UIWindow. It's tough to get it working right as a view controller in a navigation controller's view controller stack.
Your tab bar item not showing its name is a separate issue. It's because viewDidLoad is getting called before you set your item instance, specifically it's getting called when you call [tbc setViewControllers:[NSArray arrayWithObjects:photoHub, takeAPicture, nil]];
You can confirm this by breakpointing in view did load, where you'll see that item is nil. If you haven't already, you should overload your setItem: method in PhotoCollectionViewController, and have that method also update your UI.

Related

how to present UITabBarController that used UINavigationController from ViewController ouside

i have UiViewController as a LoginPage if it passed then it should show UITabBarController firstTab's ; the first tab inside UINavigationController as RootView.
how can i present firstTab from Login Page; i tried the following but error show :
Code IOS 7 StoryBoard
-(void)successLogin{
HomeTableViewController *vc =[self.storyboard instantiateViewControllerWithIdentifier:#"RootViewInControllerInFirstTabBar"];
[self presentViewController: vc animated:NO completion:nil];
}
i assume that the view that should appear after the login page should have tabs- with the first tab selected. the frst tab should have the home tableVC, which is also the root controller of a navigation controller, displayed.
[Updated]
According to my understanding of the doc, you'll first create the login page.
On successful login, the screen will navigate to a new controller derived from UITabbarViewController. Navigation to the UITabbarViewController depends on your choice, or you can even replace the view on the login screen(entirely your choice). Now on the derivedViewController you will set the viewcontrollers that you want to display on each tab using the following method of the UITabbarViewController.
- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated
On the first item of the tab bar, you will create a new controller(for profile) which will be the rootviewController of the UINavigationController.

storyboard navigation Item link to a uiviewcontroller

I create a split view project, on the iPhone's storyboard, i drag a bar button item to the navigation right and change the style Add, and i drag a view controller to the storyboard, so i use control-drag to build the link, and change the uiviewcontroller's custom class "AddViewController", when i run the project and push the DetailViewController, it is black view.
And i have input the code on the AddViewController.m
-(void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"AddViewController"];
[vc setModalPresentationStyle:UIModalPresentationCurrentContext];
[self presentModalViewController:vc animated:YES];
}
i found the reason
On the my create "AddCreateViewController", i should comment the function.
- (void)loadView
{
// If you create your views manually, you MUST override this method and use it to create your views.
// If you use Interface Builder to create your views, then you must NOT override this method.
}

Custom Image in navigationbar hiding the custom navigationbar buttons

First of all I explain what i am doing. I created a navigation based application. I have to add a custom image in the navigationbar. I added the image by using -
[self.navigationController.navigationBar insertSubview:image atIndex:0];
After this i added two custom buttons left and right to the navigation bar of the same view.I have another view and on this view i also added two custom buttons left and right to the navigation bar. All is fine till now but as i navigate to my second view my custom buttons that i am adding to the navigation controller on viewwillappear doesn't show. I used this code to add custom buttons to navigation bar -
UIBarButtonItem *customHome = [[UIBarButtonItem alloc] initWithCustomView: buttonHome];
[self.navigationController.navigationItem setLeftBarButtonItem:customHome];
Please suggest what's wrong in this. :(
You're trying to set the navigationItem on the navigation controller instead of the view controller.
If you have embedded your UIViewController in a UINavigationController then in viewDidLoad of the View Controller you could, for example, make the title a UISearchBar (that you dragged to the UIViewController in Xcode IB) and put 2 buttons on the right like this:
UIBarButtonItem *componentsButton = [[UIBarButtonItem alloc] initWithTitle:#"components" style:UIBarButtonItemStylePlain target:self action:#selector(componentsButtonTapped:)];
UIBarButtonItem *settingsButton = [[UIBarButtonItem alloc] initWithTitle:#"settings" style:UIBarButtonItemStylePlain target:self action:#selector(settingsButtonTapped:)];
self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:componentsButton, settingsButton, nil];
self.navigationItem.titleView = searchBar;
The issue here is the distinction between UINavigationController, which manages UINavigationBar, and UINavigationItem, which you and UINavigationController co-manage. (Don't forget the UINavigationBarDelegate protocol, which has little used but useful methods.)

Refreshing tabbarcontroller views on logout in iPhone application

We have a tab bar + navigation control project. We have created a tab bar through interface builder and added all tab items to the tab bar controller through through interface builder.
Our application has a login screen which we are showing as a modal form at the beginning. Once the user is authenticated, the login screen is dismissed (using dismissModalScreen) and the MainWindow is shown. This is all working fine.
Now, we have a logout option clicking on which we should show the login screen back. We are able to show that as well. But the issue is once the user is authenticated again, we want all the screens to be loaded freshly. Currently, all screens maintain their state and retain previous data.
What we have tried to do is:
[AppDelegate tabBarController release];
AppDelegate.tabBarController = nil;
We have tried releasing the tabBarController and setting it to nil. But once the view is shown, we are not able to select any of the tabs and the view is blank.
What we need is:
Once the user logs in second time, how to release and reload each viewcontroller which are part of tabbar.
Your help will be greatly appreciated.
We have found a way out. What we are doing now is, once the user logs back in, we are releasing the view controllers and recreating them and setting it back to the uitabbar.
NSMutableArray *arrControllers = [[AppDelegate.tabBarController.viewControllers] mutablecopy];
[arrControllers removeAtIndex:3];
[arrControllers removeAtIndex:2];
----Create New Controllers
UIViewController viewController2 = [[UIViewController alloc] initWithNibName:#"viewController2" bundle:nil] autorelease];
UIViewController viewController3 = [[UIViewController alloc] initWithNibName:#"viewController3" bundle:nil] autorelease];
--Create Nav controller
UINavigationController navViewController2 = [[[UINavigationController alloc] initWithRootViewController:viewController2 ] autorelease];
UINavigationController navViewController3 = [[[UINavigationController alloc] initWithRootViewController:viewController3 ] autorelease];
[arrControllers addObject:navViewController2];
[arrControllers addObject:navViewController3];
[AppDelegate.tabViewController setViewControllers:arrControllers];
It is working fine after this change.
Only problem we faced was if we release all objects from the array, we get a carsh. Is it because, when you release allObjects, the first controller which is the RootViewController is getting released?
Thanks

How to show UIToolBar at bottom of UIView after pop to root of UINavigationController?

I can't show a UIToolbar that was at the bottom of a view, where the view pushed a navigation controller and then popped back to the view using the back button.
In a NIB I've created:
UIViewController RootViewController containing a
UIView containing a
UIToolbar at bottom of UIView
In RootViewController I create next UIViewController, NextViewController, within which I create a NavigationController:
UIViewController RootViewController containing a
UIViewController NextViewController containing a
NavigationController
In NextViewController I can see the UIToolbar from RootViewController. When I pop back to NextViewController, using the back button, from the NavigationController I can no longer see the UIToolbar from RootViewController. Does anyone know how to make the UIToolbar visible?
One approach I thought would work was to get a pointer to the UIToolbar and add it as a subview to the navigation controller as:
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
RootViewController *rootViewController = appDelegate.rootViewController;
UIView *rootViewUIView = rootViewController.view;
UIToolbar *rootViewUIToolbar = rootViewUIView.toolbar;
[self.navigationController.view addSubview:rootViewUIToolbar];
But I get the error: "Request for member rootViewUIToolbar in something not a structure or a union" for the line:
UIToolbar *rootViewUIToolbar = rootViewUIView.toolbar;
Any ideas on how to show the toolbar after popping back to the root view from the navigation controller using the back button?

Resources