Issue with pushing UIViewController on UITabbarController - iphone

I have implemented UINavigationController and UITabbarController with each other. I am able to see Navigation bar and Tab bar along with UIViewController.
Problem is when I push any other UIViewController on this controller,that viewcontroller get pushed but Tabbar get disappeared.
Is there any provision to persist that UITabBar along the stack????
below is code I am referring
UIViewController* cont1 = [UIViewController alloc]init];
UIViewController* cont2 = [UIViewController alloc]init];
[tabBarController setViewControllers:[NSArray arrayWithObjects:cont1,cont2,nil]];
Thanks.

You should do it the other way around.
Place an UINavigationController in each of the UIViewController in the UITabbarController.

YourViewController *viewController = [YourViewController alloc] init] autorelease];
UINavigationController *controller = [UINavigationController alloc] initWithRootViewController:viewController] autorelease];
controller.title = #"something";
controller.tabBarItem.image = [UIImage imageNamed:#"xx"];
tabController.viewControllers = [NSArray arrayWithObject:controller];
then you can push sub view controllers into navigation controller with tab bar persistent at the bottom of the screen.

Related

Best practice when combining Tabs with Navigation

I used tabbed application template to start my new iPhone project.
I will have 4 tabs.
And I want to nave navigation bar at the top.
So I added this in AppDelegate:
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
UINavigationController *navigationcontroller = [[UINavigationController alloc] initWithRootViewController:viewController1];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:navigationcontroller, viewController2, nil];
And this added navigation bar only at the top of the first ViewController (first tab).
What I want is to add navigation bar for the whole application not just in one view.
This will enable me to jump from one view to another and back across tabs.
So what is the best way to programmatically make one navigation bar for all tab views?
UPDATE
Basically my main question is should I have one navigation bar for all views or each tab should have its own navigation bar?
What is best practice in "iDevelopers" world.
I'd rather have the self.window.rootViewController be a navigationController, and afterwards, just push your tabBarController or
NSMutableArray *viewControllers = [[NSMutableArray alloc] init];
// create someViewController
[viewControllers addObject:someView];
// create someViewController2
[viewControllers addObject:someView2];
UITabBarController *tabController = [[UITabBarController alloc] init];
[tabController setViewControllers:viewControllers];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tabController]
self.window.rootViewController = navController;
If you want to have navigation bars on each controller, you should to have UINavigationController on each tab of your UITabBarController
Look an answer to this question.
You you need navigation bar you have to add UINavigationController as you did for each view controller in tab bar. So self.tabBarController.viewControllers will have all navigation controllers.
Its not good idea to switch across tabs without user intervention.

Right design pattern for tabbed navigation views?

I've been stuck trying to puzzle this out for a couple days now, and I'll admit I need help.
The root view controller of my application is a tab bar controller. I want to have each tab bar a different navigation controller. These navigation controllers have completely different behavior.
So how do I set this up in terms of classes? Per Apple's documentation, I'm not supposed to subclass UINavigationViewController. So where do I put the code that drives each of these navigation controllers? Does it all get thrown in App Delegate? That would create an impossible mess.
This app should run on iOS 4.0 or later. (Realistically, I can probably require iOS 4.2.)
This is taken from one of my applications. As you say, you are not supposed to subclass UINavigationController, instead you use them as they are and you add viewcontroller on the UINavigationController's. Then after setting the root viewcontroller in each UINavigationController, you add the UINavigationController to the UITabBarController (phew!).
So each tab will "point" to a UINavigationController which has a regular viewcontroller as root viewcontroller, and it is the root viewcontroller (the one you add) that will be shown when a tab is pressed with a (optional) navigationbar at top.
UITabBarController *tvc = [[UITabBarController alloc] init];
self.tabBarController = tvc;
[tvc release];
// Instantiates three view-controllers which will be attached to the tabbar.
// Each view-controller is attached as rootviewcontroller in a navigationcontroller.
MainScreenViewController *vc1 = [[MainScreenViewController alloc] init];
PracticalMainViewController *vc2 = [[PracticalMainViewController alloc] init];
ExerciseViewController *vc3 = [[ExerciseViewController alloc] init];
UINavigationController *nvc1 = [[UINavigationController alloc] initWithRootViewController:vc1];
UINavigationController *nvc2 = [[UINavigationController alloc] initWithRootViewController:vc2];
UINavigationController *nvc3 = [[UINavigationController alloc] initWithRootViewController:vc3];
[vc1 release];
[vc2 release];
[vc3 release];
nvc1.navigationBar.barStyle = UIBarStyleBlack;
nvc2.navigationBar.barStyle = UIBarStyleBlack;
nvc3.navigationBar.barStyle = UIBarStyleBlack;
NSArray *controllers = [[NSArray alloc] initWithObjects:nvc1, nvc2, nvc3, nil];
[nvc1 release];
[nvc2 release];
[nvc3 release];
self.tabBarController.viewControllers = controllers;
[controllers release];
This is how I go from one viewcontroller to another one (this is done by tapping a cell in a tableview but as you see the pushViewController method can be used wherever you want).
(this is taken from another part of the app)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.detailedAnswerViewController == nil) {
TestAnsweredViewController *vc = [[TestAnsweredViewController alloc] init];
self.detailedAnswerViewController = vc;
[vc release];
}
[self.navigationController pushViewController:self.detailedAnswerViewController animated:YES];
}
The self.navigationcontroller property is of course set on each viewcontroller which are pushed on the UINavigationController hierachy.

Adding a UITabBarController programmatically with a UINavigationBarController as the first tab TO an existing Navigation Controller

I currently have a UINavigationController in my app delegate where I push a ViewController on to login. If the login is successful I want to then create a UITabBarController with a Navigation Controller as the first Tab whose root controller is a UIViewController that I am creating.
The RootViewController of my first UINavigationController is actually acting as a delegate to the logincontroller so if a user logs in correctly it calls a method in my RootViewController which is where I would then like to push a UITabBarController onto the stack. Here is my code:
UITabBarController *tbController = [[UITabBarController alloc] init];
FileBrowserViewController *fileController = [[FileBrowserViewController alloc] init];
fileController.pathToFileDB = pathToDBUnzipped;
fileController.parentId = #"0";
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:fileController];
NSMutableArray *aViewControllersArray = [[NSMutableArray alloc] initWithCapacity:2];
[aViewControllersArray addObject:navController];
[navController release];
[tbController setViewControllers:aViewControllersArray];
[self.navigationController pushViewController:tbController animated:YES];
[tbController release];
Now, it is all working fine. Except 2 things. Here is the screen shot:
1) I can't see any uitabbar items. How do i set an image and the text for each tab?
2) I don't want that top black bar. I only want 1 bar ontop with the undo button. How do I remove the additional bar?
I always follow this approach when I have both a UINavigationController and a UITabbarController:
You need to start with a view based application. And then create a UITabbarController in your appDelegate file.
Appdelegate.h
UITabBarController *tabBarController;
// set properties
Appdelegate.m
// Synthesize
tabBarController = [[UITabBarController alloc] init];
tabBarController.delegate=self;
// Adding Search,Nearby,Map,AboutUs,Favorites Tabs to tabBarController
Search * search = [[Search alloc] init];
UINavigationController *searchNav = [[UINavigationController alloc] initWithRootViewController:search];
Nearby* nearby = [[Nearby alloc] init];
UINavigationController *nearbyNav = [[UINavigationController alloc] initWithRootViewController:nearby];
Map* map = [[Map alloc] init];
UINavigationController *mapNav = [[UINavigationController alloc] initWithRootViewController:map];
AboutUs* aboutUs = [[AboutUs alloc] init];
UINavigationController *aboutUsNav = [[UINavigationController alloc] initWithRootViewController:aboutUs];
Favorites* favorites = [[Favorites alloc] init];
UINavigationController *favoritesNav = [[UINavigationController alloc] initWithRootViewController:favorites];
NSArray* controllers = [NSArray arrayWithObjects:searchNav,nearbyNav,mapNav,aboutUsNav,favoritesNav, nil];
tabBarController.viewControllers = controllers;
[window addSubview:tabBarController.view];
You can accordingly manage in which tab you want to place navigation controller or only a view controller.
Then in each of the view controllers mentioned above you need to implement
- (id)init {}
in which you can set Tab name and image.
I always follow this approach and it never fails. The tabs are always visible. You can make changes according to your code.
to hide the above black bar use -
[self.navigationController setNavigationBarHidden:TRUE];
to set tab bar item use -
for system item -
UITabBarItem *firstItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemFavorites tag:0];
for custom item -
UITabBarItem *firstItem = [[UITabBarItem alloc] initWithTitle:#"title" image:[UIImage imageNamed:#""] tag:0];
[navController setTabBarItem:firstItem];
Here is a good video on how to combine Tab Bar, Navigation Bar, and/or Table Views.
http://www.youtube.com/watch?v=LBnPfAtswgw
If you don't want you sign-up screen to have a Tab Bar controller, then you will have to present it as a modal view (since the tab bar is your root view controller). This can be done through the presentModalViewController:animated: method. You can find info about that at:
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ModalViewControllers/ModalViewControllers.html%23//apple_ref/doc/uid/TP40007457-CH111-SW1
I hope that helps. Let me know if you have any other questions!
Cheers, Evan.
hi friend that top bar is status bar . You can set.statusbar hidden = yes;
or change it from plist , when you open your plist there is a option to hide it,

How do I display the UINavigationBar on a modally presented UITableViewController?

If you have a UINavigationController's UIViewController present a UITableViewController (TVC) modally, is there a way for the TVC to display the UINavigationBar of its parentViewController? Or, should I have it create a new UINavigationBar, item, buttons, etc. for the modal TVC?
I would just instantiate a UINavigationController right before you present your modal.
YourViewController *modalViewController = [[YourViewController alloc] initWithNibName:#"foo" bundle:nil]
UINavigationController *tmpNavController = [[UINavigationController alloc] initWithRootViewController:modalViewController];
[modalViewController release];
[self.navigationController presentModalViewController:tmpNavController animated:YES];
[tmpNavController release];
This is just back-of-the-envelope - I wouldn't copy and paste that code w/o a double-check!

How to manage TabBarController on new view after viewController push action

I have a problem building applicatin with tabBarController.
There is no problem doing tabBarController with navigationController if I build it from AppDelegate.
But now I have experienced problem when I want to create new view with tabBarController (3 tabs and each has navigation controllers) after a push from previous navigation controller.
It simply doesnt work.
Here is the code:
MainViewController *mainViewController = [[MainViewController alloc] initWithNibName:#"MainView_iPhone" bundle:nil];
mainViewController.tabBarItem.title = #"First";
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:mainViewController];
DictionariesViewController *dictionariesViewController = [[DictionariesViewController alloc] initWithNibName:#"DictionariesView_iPhone" bundle:nil];
dictionariesViewController.tabBarItem.title = #"Second";
UINavigationController *dictionariesNavigationController = [[UINavigationController alloc] initWithRootViewController:dictionariesViewController];
tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [NSArray arrayWithObjects:mainNavigationController, dictionariesNavigationController, nil];
[self.navigationController pushViewController:tabBarController animated:YES];
There is a problem after view is pushe to "First" controller. Application crashes...
Please for help.
Regards
Borut
What are you trying to do with the following code?
[self.navigationController pushViewController:tabBarController animated:YES];
You said that your app has 3 tabs and each of those tabs have a navigation controller. Therefore, what you should do is to add the navigation controllers to tabBarController.viewControllers (which you did), but then you need to set the tabBarController as the root view controller.
I have done it this way and it works:
registerViewController = [[RegisterViewController alloc] initWithNibName:#"RegisterView_iPhone" bundle:nil];
AppDelegate_Phone *delegatePhone = [[UIApplication sharedApplication] delegate];
[delegatePhone.firstViewController.navigationController pushViewController:registerViewController animated:YES];
Thanks for your help guys.