I am Create already three view controller & i want to just add those view controller in tabBarview controller.
The view controller is below
First --> Login Page
Second --> Tabbar View controller
1)---> Employee View controller
2)---> Task View Controller
3)----> Home View controller
I am create above three view controller separate. I want add those in tab bar controller using Interface Builder or coding.
You can find more descriptive example from Apple docs - Combined View Controller Interfaces
I assume that Login Page is your root view controller here. Where _tabBar, _window and _loginvVewController are globally declared in the appDelegate headers files. You can also take _loginvVewController locally inside the didFinishLaunchingWithOptions method depend upon your requirements.
AppDelgate.h
UIWindow *_window;
UITabBarController *_tabBar;
LoginViewController *_loginvVewController;
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.loginvVewController = [[LoginViewController alloc] init];
// Add the tab bar controller's current view as a subview of the window
[self.window addSubview:self.loginvVewController.view];
[self.window makeKeyAndVisible];
return YES;
}
- (void)initializeTabbar {
/*
* Set up controllers for the tab bar controller
*/
EmployeeViewController *vc1 = [[[EmployeeViewController alloc] initWithTitle:#"View 1"] autorelease];
TaskViewController *vc2 = [[[TaskViewController alloc] initWithTitle:#"View 2"] autorelease];
HomeViewController *vc3 = [[[HomeViewController alloc] initWithTitle:#"View 3"] autorelease];
// View Controller with each Navigational stack support.
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:vc1];
/*
* Set up tab bar controller
*/
self.tabBar = [[UITabBarController alloc] init];
self.tabBar.viewControllers = [NSArray arrayWithObjects:navController, vc2, vc3, nil];
[self.window addSubview:self.tabBar.view];
}
In my quick hackathon for this problem, I have taken the button "Click here!" on login page - once you click on it will navigate you inside the app with tabbar. If you need the sample project then email me at d3minem#gmail.com.
After many requests via email - I have created the demo project and upload here. https://github.com/Deminem/SimpleTabbarApp--iPhone-
Please vote if you find it useful.
Good luck!
The better way would be to create a TabBarContoller based application and add the ViewControllers to the TabbarViewController.
The path is straight forward.
In IB, place your tabbar controller where you like it, make it have three pages and set their view controller classes.
Or in code, just add the tab bar controller with those three controllers set as its view controllers.
Related
Basically when i start my application I show tab view controller, and it shows first tab, and loads only first tab. I would like at the same time to preload rest of the view controllers. I have found this post - Load All TabBar Views
But I am getting error. I call [subcontroller view] in viewDidLoad method of tab bar controller. I am using storyboard. The problem is that I am getting error - Could not load NIB in bundle: 'NSBundle'
What am i missing?
EDIT:
I will try to be more concise - Tabbar has 4 view controllers, corresponding to 4 different tabs. When user presses tab, corresponding view controller is loaded. When you first launch the app, only the first view controller is loaded. Other view controllers are not loaded, they are loaded after user taps their tabs. I want all those controllers to load to memory so i can do something with them (they are not shown on screen).
// load all view controller in appdelegate.h file in project
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
ViewController1 *view1=[[ViewController1 alloc]initWithNibName:nil bundle:nil ];
view1.tabBarItem.image = [UIImage imageNamed:#"1.jpg"];
UINavigationController *navi1=[[UINavigationController alloc]initWithRootViewController:view1];
ViewController2 *view2=[[ViewController2 alloc]initWithNibName:nil bundle:nil ];
view1.tabBarItem.image = [UIImage imageNamed:#"1.jpg"];
UINavigationController *navi2=[[UINavigationController alloc]initWithRootViewController:view2];
NSArray *navi= [[NSArray alloc]initWithObjects:navi1,navi2,navi3,navi4,nil];
UITabBarController * bar=[[UITabBarController alloc]init];
NSArray *navi= [[NSArray alloc]initWithObjects:view1,view2,nil];
bar.viewControllers=navi;
[self.bar setViewControllers:navi animated:YES];
self.window.rootViewController=self.bar;
[self.window addSubview:bar.view];
[self.window makeKeyAndVisible];
return YES;
}
}
Like what i understand u wanna to load all other view and set it ready to lunch it when u press on tap :)
if that what u want u can load it and build it all in background and add it to view but u need to hide it until u press u show the view u want and hide the other views.
this answer work if u build your custom tab :)
I am very new to the iPad UISplitViewController.
I need to add a tab bar containing 3 tabs at the bottom of the master view / left view. I have a different View Controller for each of the 3 tabs. I haven't found any other examples of Tab bars being used in split view based applications.
Where do I insert a tab bar controller for displaying at the bottom of the the root view?
How do I establish a connection so that when I select a table cell, the detailItem info gets displayed in the Detail View? Tab bar was added to the Root View in IB. Should I be adding it programmatically instead?
in your app delegate add tabbar controller then add your view controllers to tabbar controller and set the window rootview controller to tabbar controller.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.tabbar=[[UITabBarController alloc] init];
self.vc1 = [[vc1 alloc] initWithNibName:#"ViewController_iPhone" bundle:nil];
// do the same to other VCs
self.tabbar.viewControllers=[NSArray arrayWithObjects:vc1,vc2,vc3,vc4, nil];
self.window.rootViewController = self.tabbar;
[self.window makeKeyAndVisible];
return YES;
}
i hope it helps :-)
you have to take UITabBarController dynaically.
In .h file
UITabBarController *tabBar;
in .m file
create objects to your classes in appDidFinish Launch
For example you have
Class1 and Class2
in appDidFinishLaunch
Class1 *obj1=[Class1 alloc]initWithNibName:#"Class1" bundle:nil];
**Class2 obj2=[Class2 alloc]initWithNibName:#"Class2" bundle:nil];*
// Master navigation controller by defaults comes with template code
// Now you have create Array for tabBar
NSArray *tabViewArray=[[NSArray alloc] initWithObjects:obj1,obj2,masterNavigationController, nil];
tabBar=[[UITabBarController alloc] init];
[tabBar setViewControllers:tabViewArray];
// now you have to edit the statement which contains splitview.viewArray repalce masterNavigataionControler with tabBar
self.splitViewController.viewControllers = [NSArray arrayWithObjects:tabBar, detailNavigationController, nil];
Try this i hope it will helps you.
All you have to do is initialize the first argument of uispliviewcontroller for view as tabbar instead of a view or you can use uisegmentedcontrol.
New to iOS development, I've been following the tutorials on developer.apple.com, and am now adding functionality to those examples to further my knowledge.
The "second ios app" tutorial gives you a navigation controller based app. Extending this app, I want to have a tab bar controller as the first view controller.
So I now have the following setup:
All good. But there is code in the BirdsAppDelegate (a UIApplicationDelegate) which was relying on the navigation controller being the root view controller, so it can create and assign the "datacontroller" object.
This is the original code (before I added the tab bar controller):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
BirdsMasterViewController *firstViewController = (BirdsMasterViewController *)[[navigationController viewControllers] objectAtIndex:0];
BirdSightingDataController *aDataController = [[BirdSightingDataController alloc] init];
firstViewController.dataController = aDataController;
return YES;
}
Now this code fails because it assumes the root view controller is the navigation controller.
I have updated the code so that it works - but in my opinion it is ugly, and would have to be changed every time I make a change to the view controller hierarchy:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
UINavigationController *navigationController = (UINavigationController *) [[tabBarController viewControllers] objectAtIndex:0];
BirdsMasterViewController *firstViewController = (BirdsMasterViewController*) [[navigationController viewControllers] objectAtIndex:0];
BirdSightingDataController *aDataController = [[BirdSightingDataController alloc] init];
firstViewController.dataController = aDataController;
return YES;
}
So my question is: What is the better way to do what I am doing in the code above, so that any changes to the hierarchy will not break the code?
How do I programmatically access the view controller I am after in the application delegate, so that I can create and assign it's BirdSightingDataController object?
Thanks!
You can loop the [navigationController viewControllers] array looking for an instance of BirdsMasterViewController... Using [obj isKindOfClass:[BirdsMasterViewController class]].
You don't even need that code at a all. If you just want to change the controller, go to the storyboard and select the viewController you want to change to a TabBarController. In the Editor menu, there is an option for "Embed In", the choices are TabBar and Navigation controllers.
I always start with a single view application template. There is no code in the "application didFinishLaunchingWithOptions:" method,(except to return YES). You can set any viewController as your initial view in the storyboard, by setting the is initial View Controller check box, or just dragging the arrow to the viewController you want as your initial view.
My project is a view based project to start off.
So app delegate launches as per normal.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
Then my first viewcontroller is called and it shows two UITextFields so the user can enter their credentials and log on.
When that succeeds I call another view controller in which I add a UINavigationController and a UITabBarController to the view. As can be seen below.
- (void)viewDidLoad
{
[super viewDidLoad];
UINavigationController *localNavigationController;
tabBarController = [[UITabBarController alloc] init];
NSMutableArray *localControllersArray = [[NSMutableArray alloc] initWithCapacity:2];
Hello *firstViewController;
firstViewController = [[Hello alloc] init];
localNavigationController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
[localNavigationController.tabBarItem initWithTitle:#"Test" image:[UIImage imageNamed:#"tabBarIcon.png"] tag:1];
//[localNavigationController.tabBarItem initWithTabBarSystemItem:UITabBarSystemItemDownloads tag:1];
firstViewController.navigationItem.title=#"New Requests";
[localControllersArray addObject:localNavigationController];
[localNavigationController release];
[firstViewController release];
Test *secondViewController;
secondViewController = [[Test alloc] init];
localNavigationController = [[UINavigationController alloc] initWithRootViewController:secondViewController];
[localNavigationController.tabBarItem initWithTitle:#"Test" image:[UIImage imageNamed:#"tabBarIcon.png"] tag:2];
secondViewController.navigationItem.title=#"Existing";
[localControllersArray addObject:localNavigationController];
[localNavigationController 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
[self.view addSubview:tabBarController.view];
}
This seems to work ok, so far. There was a problem off both the Navbar and Tabbar being dropped to low by the height of the status bar, but that was corrected once i hid the status bar.
Is there any reason I should not do things this way? Is it bad practice or will i run into some problems with it down the road?
I could set up both the Navbar and the Tabbar from the app delegate and just hide them both during the log-on screen. That's the only other option I see.
I appreciate any feedback that you guys can offer. I feel nervous about the results of what I have done so far, expect it might blow up in my face.
Many Thanks,
-Code
You should generally not directly add the views of UINavigationController and UITabBarController as subviews of your own view controllers. This kind of 'view controller containment' is tricky to get right unless you use the new iOS 5 APIs.
The reason is that the actual view controllers will not receive certain important messages like viewDidAppear: and rotation messages. You will notice strange rotation bugs and other weird issues cropping up. You can forward these methods yourself from the parent view controller and things will work OK, but in your case you have no need to do this because you're just trying to show a standard tab bar controller.
Generally you should have one view controller set up as the UIWindow's root view controller. This is normally a UINavigationController, UITabBarController, etc. The parent UIWindow will send rotation events and other messages to this controller. The standard 'container' controllers like UITabBarController will then forward these messages to their children so everything works correctly.
If I were you, I would always have the tab bar controller as the window's root view controller. When your app starts (i.e. in application:didFinishLaunchingWithOptions:), create an empty tab bar controller and set it up as the root view controller:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// create a basic empty tab bar controller
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
// ...
// Set up the window's root view controller
self.window.rootViewController = tabBarController;
// ...
}
Now, whenever you present stuff on the screen, it should be a child of the root view controller, in your case the tab bar controller.
So once the root view controller is set up, you can check to see if the user is already logged in. If they are, you can then set up your navigation controller and the tab items, and add them to the tab bar controller.
If the user is not logged in, you can show your login view controller over the top of the tab bar controller using presentModalViewController:animated::
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// ...
// Set up the window's root view controller
self.window.rootViewController = tabBarController;
if (isUserLoggedIn()) {
[self setupTabsAndStuff];
} else {
LoginViewController *loginVC = [[[LoginViewController alloc] init] autorelease];
[self.tabBarController presentModalViewController:loginVC animated:NO];
}
// ...
}
The animated:NO will cause the login screen to be immediately visible after starting the app with no animation.
Once the user enters correct details you can again call your setupTabsAndStuff method and dismiss the login view controller again.
So to summarize:
Rather than having your own UIViewController into which you place the tab bar controller's view, just use the tab bar controller directly.
Install the tab bar controller as the window's root view controller. The tab bar controller will then correctly forward rotation events and other special messages to the view controllers it contains.
Always present views and view controllers as children of the root view controller. If you need to show something full-screen use presentModelViewController:animated
Try to set the frame of *tabBarController.
[tabBarController.view setFrame:self.view.bounds];
// add the tabBarController as a subview in the window
[self.view addSubview:tabBarController.view];
I'm making an iphone app out of the utility template in xcode. So in my FlispSideView I have a button that should show a custom image picker. I decided to use this nice one here link.
Now I made some changes cuz I'm not using a navigation controller to load the custom image picker (but rather modally) which is created programmatically inside the .m file. So I made the FlipSideView the delegate for the custom image picker but still lost when I come to loading the view. I created a xib file and tried to connect it to the image picker but that didn't work.
So I wonder what's the best way to do that?
I'm not sure I interpreted your question correctly, but based on the title, I think this might be what you are looking for:
// Initialize your custom controller and set the delegate
UIViewController *controller = [[UIViewController alloc] initWithNibName:#"MyView" bundle:nil];
controller.delegate = self;
// Set the title of your custom controller (optional)
controller.title = NSLocalizedString(#"My View", nil);
// Create a navigation controller with your custom controller as the root view controller
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:controller];
// Present the navigation controller as a modal view controller
[self.navigationController presentModalViewController:navCon animated:YES];
// Release objects you own
[navCon release];
[controller release];
If your image picker is a controller, and all the outlets on your xib are properly connected to it, this should work. You should be able to make your FlipSideView the delegate. Pressing cancel or done in the modal view should call a message in the delegate that says
[self.navigationController dismissModalViewControllerAnimated:YES];
EDIT:
Here is the first line of my example code updated to match the tutorial you are using:
CustomImagePicker *controller = [[CustomImagePicker alloc] init];
The rest is the same. You initialize a navigation controller with controller as the root view controller, then present the navigation controller as a modal view controller.
Creating navigation programatically
Use the code below to navigate programatically. Write the following code in
AppDelegate.m class
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
FirstViewController *firstViewController = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
self.nav = [[UINavigationController alloc] initWithRootViewController:firstViewController];
[_window addSubview:nav.view];
[_window makeKeyAndVisible];
}