I have an app with a custom UITabBarController that contains five view controllers. Within each of these view controllers, other view controllers can be accessed. Ideally, I would like my custom UITabBarController to appear in each ViewController-regardless on whether or not the view controller originates directly from the tabbar.
I think this can be accomplished using a Navigation Controller within each of the original five view controllers, however, is there a way to just add the custom UITabBarController to each view controller? I tried doing this by the following ways in my viewDidLoad methods:
AppDelegate *appDelegate = [(AppDelegate *)[UIApplication sharedApplication] delegate];
tabbarController = appDelegate.tabBarController;
tabbarController.view.frame = CGRectMake(0, 0, 320, 480);
[self.view addSubview:tabbarController.view];
but I get a bad_access in my app delegate when I run the code.
Any thoughts?
As you correctly stated, using 'UINavigationController's as root controllers of each tab will achieve what you are trying to do.
Here is an example of how to easily setup your tabbar with navigation controllers:
- (void)setupTabBar {
// Create nav-controller for local use
UINavigationController *localNavController;
// New tabbar controller and array to contain the view controllers
UITabBarController * theTabBarController = [[UITabBarController alloc] init];
NSMutableArray *localViewControllersArray = [[NSMutableArray alloc] initWithCapacity:4];
/*--------------------------------------------------------------------
* Setup the view controllers for the different tabs
*-------------------------------------------------------------------*/
// Root view controller for Tab 1
UIViewController *vc;
vc = [[ViewController1 alloc] initWithNibName:#"ViewController1" bundle:nil];
localNavController = [[UINavigationController alloc] initWithRootViewController:vc];
localNavController.tabBarItem.image = [UIImage imageNamed:#"image.png"];
localNavController.tabBarItem.title = #"Tab1";
// Add navigation controller to the local vc array (1 of 4)
[localViewControllersArray addObject:localNavController];
// Root view controller for Tab 2
vc = [[ViewController2 alloc] initWithNibName:#"ViewController2" bundle:nil];
localNavController = [[UINavigationController alloc] initWithRootViewController:vc];
localNavController.tabBarItem.image = [UIImage imageNamed:#"image.png"];
localNavController.tabBarItem.title = #"Tab2";
// Add navigation controller to the local vc array (2 of 4)
[localViewControllersArray addObject:localNavController];
// Root view controller for Tab 3
vc = [[ViewController3 alloc] initWithNibName:#"ViewController3" bundle:nil];
localNavController = [[UINavigationController alloc] initWithRootViewController:vc];
localNavController.tabBarItem.image = [UIImage imageNamed:#"image.png"];
localNavController.tabBarItem.title = #"Tab3";
// Add navigation controller to the local vc array (3 of 4)
[localViewControllersArray addObject:localNavController];
// Root view controller for Tab 4
vc = [[ViewController4 alloc] initWithNibName:#"ViewController4" bundle:nil];
localNavController = [[UINavigationController alloc] initWithRootViewController:vc];
localNavController.tabBarItem.image = [UIImage imageNamed:#"image.png"];
localNavController.tabBarItem.title = #"Tab4";
// Add navigation controller to the local vc array (4 of 4)
[localViewControllersArray addObject:localNavController];
// Point the tab bar controllers view controller array to the array
// of view controllers we just populated
theTabBarController.viewControllers = localViewControllersArray;
self.tabBarController = theTabBarController;
[self.window setRootViewController:self.tabBarController];
...
}
Hope this helps :)
Your AppDelegate should have one TabBarController. This TabBarController holds an array of ViewControllers (tabBarController.viewControllers).
These ViewControllers should be UINavigation Controllers.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UINavigationController* navController1 = [[UINavigationController alloc] initWithRootViewController:firstOfYourControllers;
UINavigationController* navController2 = [[UINavigationController alloc] initWithRootViewController:sencondOfYourViewControllers;
UINavigationController* navController3 = [[UINavigationController alloc] initWithRootViewController:andSoOn;
UINavigationController* navController4 = [[UINavigationController alloc] initWithRootViewController:andSoOn;
UINavigationController* navController5 = [[UINavigationController alloc] initWithRootViewController:andSoOn;
NSArray* viewControllerArray = [NSArray arrayWithObjects:navController1, navController2, navController3, navController4, navController5, nil];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = viewControllerArray;
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
Do not present your NavigationControllers modally. They will be presented on top of your TabBarController and the TabBarController won't be visible anymore. Do also not try to present a TabBarController in a NavigationController.
Related
I've been looking at programatically adding a tab bar to my view controller because having a scroll view I can't place it on without it being in the middle of my view. I'm abit confused about how to add it. Does it need to be initiated in my ViewDidLoad method or my AppDelegate?
If I have:
UITabBarController *tabBar = [[UITabBarController alloc] init];
[self.view addSubview:tabBar.view];
[tabBar release];
How can I allocate it to the bottom of my scrollview?
Thanks!
Now in my appDelegate class :
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UITabBarController *tabBarController = [[UITabBarController alloc] init];
ViewController* vc = [[ViewController alloc] init];
NSArray* controllers = [NSArray arrayWithObjects:vc, tabBarController, nil];
tabBarController.viewControllers = controllers;
[_window addSubview:tabBarController.view];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
It's crashing and not sure if it's a release I'm missing.
Edit:
For anyone else wondering this in Appdelegate.m:
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = #[viewController1, viewController2, viewController3, viewController4];
Take a look at this Documentation given by Apple: ViewControllers.
Sample Code :
- (void)applicationDidFinishLaunching:(UIApplication *)application {
UITabBarController *tabBarController = [[UITabBarController alloc] init];
FirstViewController* vc1 = [[FirstViewController alloc] init];
SecondViewController* vc2 = [[SecondViewController alloc] init];
NSArray* controllers = [NSArray arrayWithObjects:vc1, vc2, nil];
tabBarController.viewControllers = controllers;
// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];
}
I did it this way. I copied this from my App Delegate and it works fine. Basically you add the view controllers to the tab bar then add the tab bar to the window's subview.
Instantiate the instance
iVacationTabBar = [[UITabBarController alloc] init];
However you create the views/view controllers:
UINavigationController *rvc_tools = [[UINavigationController alloc] initWithRootViewController: vc_tools];
UINavigationController *rvc_settings = [[UINavigationController alloc] initWithRootViewController: vc_settings];
UINavigationController *rvc_about = [[UINavigationController alloc] initWithRootViewController: vc_about];
UINavigationController *rvc_currentpage = [[UINavigationController alloc] initWithRootViewController: vc_currentpage];
UINavigationController *rvc_backup = [[UINavigationController alloc] initWithRootViewController:vc_backup];
Add the controllers to the array:
NSArray* controllers = [NSArray arrayWithObjects: rvc_currentpage, rvc_tools,rvc_settings, rvc_backup, rvc_about, nil];
Set the array of view controllers to your tab bar:
[iVacationTabBar setViewControllers: controllers animated:NO];
Add the tab bar to the window's subview.
[_window addSubview:iVacationTabBar.view];
You can not add a UITabbarController on a UIViewController. Instead, on a ViewController you have to show the TabbarController, create a TabbarController, set ViewControllers for it, and add it to a Window.
I have an activation page in my app, which is mandatory for every user to activate the app.
Once the app is activated, the user moves to the tabbed bar view.
I have created a tabbed bar application, where from my activationView on click of button I am trying to call the tab bar, I am getting an entire black screen.
- (IBAction)moveToActivateView:(id)sender {
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
UITabBarController *tabBarController = [[UITabBarController alloc]init];
[self.view addSubview:tabBarController.view];
appDelegate.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
self.tabBarController.viewControllers = #[viewController1, viewController2];
appDelegate.window.rootViewController = self.tabBarController;
[appDelegate.window makeKeyAndVisible];}
Hey make your tabBarController's property in appDelegate and assign all ViewController there then call your tabBarController from yourViewController
in AppDelegate.h
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
#property (retain, nonatomic) IBOutlet UITabBarController *tabBarController;
in AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self makeTabBar];
[self addInitialVIew];
[self.window makeKeyAndVisible];
return YES;
}
-(void)makeTabBar
{
tabBarController = [[UITabBarController alloc] init];
tabBarController.delegate=self;
FirstViewController *firstVC =[[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UINavigationController *firstNC = [[UINavigationController alloc] initWithRootViewController:firstVC];
firstNC.tabBarItem.title=#"Profile";
firstVC.tabBarController.tabBar.tag = 0;
SecondViewController *secondVC = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
UINavigationController *SecondNavController = [[UINavigationController alloc] initWithRootViewController:secondVC];
SecondNavController.tabBarItem.title = #"Search";
secondVC.tabBarController.tabBar.tag = 1;
NSArray *viewControllers =[[NSArray alloc]initWithObjects:firstNC,SecondNavController, nil];
[tabBarController setViewControllers:viewControllers animated:NO];
}
-(void) addInitialVIew
{
InitialViewController *initialViewController = [[InitialViewController alloc]initWithNibName:#"InitialViewController" bundle:nil];
navigationController = [[UINavigationController alloc]initWithRootViewController:ViewController];
[self.window addSubview:navigationController.view];
}
Now in InitialViewController you can add yourTabBar and remove InitialViewController
- (IBAction)switchToTabBarBtnPress:(id)sender
{
AppDelegate *appdelegte =(AppDelegate*)[[UIApplication sharedApplication]delegate];
[[[appdelegte navigationController] view]removeFromSuperview];
[[appdelegte window]addSubview:[[appdelegte tabBarController]view]];
[[appdelegte tabBarController]setSelectedIndex:0];
}
And Follow my answer
Answer
You want to create dynamic tabbar application to resolve your problem. So you just create the view based application. in the view controller viewdidload method put these code
tabbar1 = [[UITabBarController alloc] init];
artist_tab_obj = [[artist_tab alloc] initWithNibName:#"artist_tab" bundle:nil];
UINavigationController *tabItem1 = [[[UINavigationController alloc] initWithRootViewController: artist_tab_obj] autorelease];
tabItem1.title=#"Artist";
tabItem1.tabBarItem.image=[UIImage imageNamed:#"Icon1.png"];
music_tab_obj = [[music_tab alloc] initWithNibName:#"music_tab" bundle:nil];
UINavigationController *tabItem2 = [[[UINavigationController alloc] initWithRootViewController: music_tab_obj] autorelease];
tabItem2.title=#"Music";
tabItem2.tabBarItem.image=[UIImage imageNamed:#"Icon2.png"];
shout_tab_obj = [[shout_tab alloc] initWithNibName:#"shout_tab" bundle:nil];
UINavigationController *tabItem3 = [[[UINavigationController alloc] initWithRootViewController: shout_tab_obj] autorelease];
tabItem3.title=#"Shout";
tabItem3.tabBarItem.image=[UIImage imageNamed:#"Icon3.png"];
schedule_tab_obj = [[schedule_tab alloc] initWithNibName:#"schedule_tab" bundle:nil];
UINavigationController *tabItem4 = [[[UINavigationController alloc] initWithRootViewController: schedule_tab_obj] autorelease];
tabItem4.title=#"Schedule";
tabItem4.tabBarItem.image=[UIImage imageNamed:#"Icon4.png"];
follow_tab_obj = [[follow_tab alloc] initWithNibName:#"follow_tab" bundle:nil];
UINavigationController *tabItem5 = [[[UINavigationController alloc] initWithRootViewController: follow_tab_obj] autorelease];
tabItem5.title=#"Follower";
tabItem5.tabBarItem.image=[UIImage imageNamed:#"Icon5.png"];
tabbar1.viewControllers = [NSArray arrayWithObjects:tabItem1, tabItem2,tabItem3,tabItem4,tabItem5,nil];
In user acceptation is yes button action call this code.
[self.view insertSubview:tabbar1.view belowSubview: artist_tab_obj.view];
tabbar1.selectedIndex=1;
[self presentModalViewController:tabbar1 animated:YES];
Did you realize that your local varialbe tabBarController is not identical but sort of hides the property self.tabBarController? You create a new UITabBarCotnroller and assign it to your local variable tabBarController, which is accessible from this method only. Then you manipulate (add newly created view controllers) etc to self.tabBarController. Self.tabBarController could easily be nil here or anything else. But it is not the very UITabBarController that you just created.
And it is self.tabBarController (so probably nil) what you assign to the window as rootViewController.
You do add the tabBarController's view as subview to self.view. Besides that I do not know what self acutally is, I don't think is it really nessessary to manually add the tabBar's view as subview. Setting the root view controller (properly) should be enough
I am developing one application which includes view controller because my first two pages content only view not tab-bar.after that i have created run time tab-bar controller using this code
UIViewController *viewcontroller1 = [[viewcontroller1 alloc] initWithNibName:#"viewcontroller1" bundle:nil];
viewcontroller1.title = #"sometext";
viewcontroller1.tabBarItem.image = [UIImage imageNamed:#"someimage.png"];
UIViewController *viewcontroller2 = [[viewcontroller2 alloc] initWithNibName:#"viewcontroller2" bundle:nil];
viewcontroller2.title = #"sometext";
viewcontroller2.tabBarItem.image = [UIImage imageNamed:#"someimage.png"];
tbc = [[UITabBarController alloc] initWithNibName:#"viewcontroller1" bundle:nil];
tbc.viewControllers = [NSArray arrayWithObjects: viewcontroller1,viewcontroller2, nil];
tbc.selectedViewController = viewcontroller1;
//// NSLog(#"Selected index = %d of %d", tbc.selectedIndex, [tbc.viewControllers count]);
[self presentModalViewController:tbc animated:NO];
it is working properly but in my second view i want tab-bar controller and navigation-controller both.
so in viewcontroller2 i have implemented code like that it's giving me navigation controller but it's hiding tab-bar controller
- (void)viewDidLoad
{
nvc = [[UINavigationController alloc] initWithRootViewController:[[viewcontroller2 alloc] initWithNibName:#"viewcontroller2" bundle:nil]];
[self presentModalViewController:nvc animated:NO];
[nvc release];
[super viewDidLoad];
}
so please help me what to i do so i can get both tab-bar controller & navigation-controller in this viewcontroller2.??
please guide me.
You can create new class for tabbar and in UI Design time you can add navigation controller as tab and set view in navigation controller. Whenever you want add tabbar controller in that page create object of tabbarcontroller class object and add it on view.
I am adding view controller in navigation controller and then adding it to tab bar controller. but if i add this like
navigationController.viewControllers =
[NSArray arrayWithObjects:rootViewController, rootViewController.photoViewController, nil];
tabBarController.viewControllers = [NSArray arrayWithObjects:tourNavigation,mapNavigation ,browserNavigation,
navigationController,nil];
This is not showing tab with fourth navigation controller.. other controllers are simple as
BrowserViewController *browserView = [[BrowserViewController alloc]initWithNibName:#"BrowserViewController"
bundle:nil];
browserView.title = #"Browser";
UINavigationController *browserNavigation = [[[UINavigationController alloc]initWithRootViewController:browserView]
autorelease];
This is working fine.. but navigation with array is not displaying.
I don't think you should be setting the navigation controller's viewControllers array like that. Instead try:
navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
[navigationController pushViewController:rootViewController.photoViewController animated:NO];
This is assuming that you want the photo view controller to be showing when the user taps on the tab. It will be on top of the navigation controller's stack.
You need to start with view based application. And then create a UITabbarController in you appDelegate file.
Appdelegate.h
UITabBarController *tabBarController;
// set properties
Appdelegate.m
// Synthsize
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.
My program is not supporting the UIInterfaceOrientation. Program will not support the UIInterfaceOrientation after I add the UITabBarItem.Please give a solution. Also I added the navigationController.
Here is my code.
-(void) applicationDidFinishLaunching:(UIApplication *)application {
//I create my navigation Controller
//UINavigationController *navigationController;
//I create my TabBar controlelr
tabBarController = [[UITabBarController alloc] init];
// Icreate the array that will contain all the View controlelr
NSMutableArray *localControllersArray = [[NSMutableArray alloc] initWithCapacity:2];
// I create the view controller attached to the first item in the TabBar
sivajitvViewController *firstViewController;
firstViewController = [[sivajitvViewController alloc]init];
navigationController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
//[navigationController.tabBarItem initWithTabBarSystemItem:UITabBarSystemItemFavorites tag:1];
firstViewController.navigationItem.title=#"Gallery";
//viewController.tabBarItem.image = [UIImage imageNamed:#"natural.jpg"];
navigationController.tabBarItem.image = [UIImage imageNamed:#"Gallery.png"];
navigationController.tabBarItem.title = #"Gallery";
//navigationController.headerTitle = #"Some Title";
[localControllersArray addObject:navigationController];
[navigationController release];
[firstViewController release];
// I create the view controller attached to the second item in the TabBar
SecondViewController *secondViewController;
secondViewController = [[SecondViewController alloc] init];
navigationController = [[UINavigationController alloc] initWithRootViewController:secondViewController];
//[navigationController.tabBarItem initWithTabBarSystemItem:UITabBarSystemItemContacts tag:2];
navigationController.tabBarItem.image = [UIImage imageNamed:#"News.png"];
navigationController.tabBarItem.title = #"News";
[localControllersArray addObject:navigationController];
[navigationController release];
[secondViewController release];
// load up our tab bar controller with the view controllers
tabBarController.viewControllers = localControllersArray;
// release the array because the tab bar controller now has it
[localControllersArray release];
// add the tabBarController as a subview in the window
[window addSubview:tabBarController.view];
// need this last line to display the window (and tab bar controller)
[window makeKeyAndVisible];
}
If you have UITabBarController, all the tabs should support your interface orientation. So if you have 3 tabs and 2 of them support portrait and landscape, but the last one supports only portrait, you application will never turn to landscape.