Add a XIB view to a tab view in the storyboard - objective-c

I am working on an Iphone application.
I am using a StoryBoard.
I have a Tab View with 3 tabs. "Home", "Users" and "Settings".
I create the "Home" and "Users" view on the story board, but The settings view is a XIB file (SettingsView.xib)
How can I make the third tab ("Settings") open the SettingsView.xib? Can I use both the story board and xib files?
I tried to initialize a UINavigationController in the startApp method in the AppDelegate but I can't find out how to add it to the story board.
Thanks for any help

TabViewControllers usually have one navigation controller for each tab.
Create the navigation controllers in storyboard and connect them to the navigationcontrollers relation of the tab view controller.
The initial view of the navigation controller connects to the rootViewController relationship of the navigation controller.
As to your second question, I'm not certain, but I think the following will work:-
Create a UIViewController in storyboard and change it's class to your class that you're loading from an XIB. When the storyboard instantiates the class, it will use the XIB provided the class name of the class exactly matches the name of the XIB. I don't think you can do any iPad/iPod checking here though.

You can add a xib-based view to your storyboard-based tab bar controller as follows. I am assuming the following:
The tab bar controller is the initial view controller of your storyboard.
Your settings controller is a class called SettingsController
You have a tab bar image in your bundle called SettingsTabImage
Define the tab bar controller in the storyboard with just your storyboard-based tab bar items in it - Home and Users in your case
In your application delegate, use the following code in application:didFinishLaunchingWithOptions::
// Create your settings view controller
SettingsController *settingsVC = [[SettingsController alloc] initWithNibName:nil bundle:nil];
// Create a tab bar item
UITabBarItem *settingsItem = [[UITabBarItem alloc] initWithTitle:#"Settings" image:[UIImage imageNamed:#"SettingsTabImage" tag:0];
settingsVC.tabBarItem = settingsItem;
// Get a reference to the tab bar controller
UITabBarController *tbC = (UITabBarController*)self.window.rootViewController;
// Get the current view controllers in your tab bar
NSMutableArray *currentItems = [NSMutableArray arrayWithArray:tbC.viewControllers];
// Add your settings controller
[currentItems addObject:settingsVC];
tbC.viewControllers = [NSArray arrayWithArray:currentItems];

Related

How to access Tab View Controller from another View Controller

I'm having trouble accessing my view controllers under the tab bar controller. Here is what my storyboard looks like:
View Controller A (-> Page View Controller -> View Controller C
View Controller A -> Tab Bar Controller (MyTabBarController.h/.m) -> Navigation Controller (MyNavigationController.h/.m)-> View Controller B (TabViewController.h/.m)
Tab Bar Controller (MyTabBarController.h/.m) -> View Controller D
Tab Bar Controller (MyTabBarController.h/.m) -> View Controller E
From View Controller A I have an IBAction called loginButton that is connected to the Tab Bar Controller, and currently it looks like this:
- (IBAction)loginButton:(id)sender {
MyNavigationController *localNavigationController;
UIStoryboard * storyboard = self.storyboard;
MyTabBarController *tbc = [[MyTabBarController alloc] init];
NSMutableArray *localControllersArray = [[NSMutableArray alloc] initWithCapacity:1];
TabViewController *login = [storyboard instantiateViewControllerWithIdentifier: # "TabViewController"];
localNavigationController = [[UINavigationController alloc] initWithRootViewController:login];
localNavigationController.delegate = self;
[localControllersArray addObject:localNavigationController];
tbc.viewControllers = localControllersArray;
tbc.delegate = self;
tbc.moreNavigationController.delegate = self;
tbc.selectedIndex = 0;
[self presentViewController:tbc animated:YES completion:^{
}];
}
I'm not able to get this displayed correctly. I am getting a bunch of warnings in this piece of code. and it is also not showing the different tab items in the bottom of the Tab Bar, even though I have put images/text on each tab.
So how do I display/access the view controllers inside the Tab Bar Controller correctly? (ie View Controllers C/D/E)?
The storyboard that you show in your question already contains the tab bar controller, navigation controller, and login controller properly hooked up to each other. Because of that, you shouldn't be instantiating a new tab bar controller or navigation controller in code -- they will be instantiated by the storyboard when you instantiate the tab bar controller. So, the only thing you need to do, is to give the tab bar controller in the storyboard an identifier, and do this (assume the identifier is called MyTabBarController):
- (IBAction)loginButton:(id)sender {
UITabBarController *tbc = [self.storyboard instantiateViewControllerWithIdentifier:#"MyTabBarController"];
[self presentViewController:tbc animated:YES completion:nil];
}
You wouldn't even need this code if you control drag from the "Login" button to the tab bar controller, and choose "Modal". That will create a modal segue which will present the tab bar controller with no code at all.
If you just want to select another tab from the tabBar controller then use something like this:
UITabBarController *tabBar = (UITabBarController *)self.window.rootViewController;
[tabBar setSelectedIndex:3];
Note that if the tabBar controller is the initial view controller you can grab an instance of it it the applicationDidFinishLaunching method and store it in the AppDelegate. Then you'll be able to access it like this:
MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
Remember to import the AppDelegate.h
I recommand you to use a Singleton shared instance to share multiple informations form multiple controllers.
It's a good design Pattern for you usage.
I'm writing samples of Design Patterns usage on cocoa (see https://github.com/leverdeterre/DesignPatterns -> Real singleton)

How to get the Xcode TabView default black bar in bottom?

In a new tabbed app application when two more views are added, views which are created by default has a black bar on bottom and the two views that are manually created doesn't have that black bar ?
How to enable that black bar ?
You need to connect your two other scenes to the tab bar controller. Hold the control key down, and drag from Tab Bar View Controller to the other View Controller. When it asks what type of a segue you want to create, choose "view controllers" under the "Relationship" segue section.
If you are using NIBs, drag a view controller object from the object library into the tab bar controller. Once it's there, select the new view controller in the view controller explorer and configure the Custom Class in the Identity Inspector.
... and the name of the nib in the Attributes Inspector.
In your app delegate you should see code like this:
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[viewController1, viewController2];
Modify it to include your third and fourth view controllers. Otherwise, how would your tab controller know your new view controllers exist!

How to create a tab bar on iOS?

I need on my main view controller to have a tab bar with tabs to navigate to all my other controllers. I just need the tab bar on this controller and when i get to another controller i just need to have a back button to go to the main controller.
Now i have some questions. I created the tab bar in the main view controller and all the tabs with the text and images that i need. However i see that i can only create IBOutlet for the tab bar and not IBActions for every tab(as i thought). So i created an IBOutlet and connected it to my tab bar.
How can i refer to every tab?
If i can refer to every tab how is it possible to change the view controller when a tab is selected when i cant use an action about it?(I am not asking for the code to change controllers , i am asking for the place that i should put the code so that my application knows that this specific tab was pressed and has to change controller).
Thank you for reading my post :D
You can create a UITabBarController programmatically in applicationDidFinishLaunching and set it as the root view controller (or if you prefer, you can present it as a modal view). Here is the minimal code to do it:
UITabBarController *tabBarController = [[UITabBar alloc] init];
UIViewController *controller1 = [[YourViewController alloc] init];
UIViewController *controller2 = [[YourOtherViewController alloc] init];
tabBarController.viewControllers = [NSArray arrayWithObjects:
controller1,
controller2,
nil];
// set as the root window
window.rootViewController = tabBarController;
If you want to customize the look of the tab bar items, do so by adding overloading (UITabBarItem *)tabBarItem in the child view controller(s):
- (UITabBarItem *)tabBarItem
{
return [[UITabBarItem alloc] initWithTitle:#"Amazing" image:[UIImage imageNamed:#"Blah.png"] tag:0];
}
How to make a tab bar controller
by me
Drag tab bar controller into storyboard (hopefully you have one)
Control-drag from tab bar controller to each view you want hooked up to it
Pop bottles
Just so you know, this gives you the default tab bar controller behavior (so it will always be present and you can click from any page to another). If that's not what you want, then don't use a tab bar controller. To do otherwise is an abomination.
Storyboards are definitely helpful, but if you don't want to use one that's fine. Doing the Control Drag from the Tab Bar Controller to your new View Controller does indeed work (Dustin's response).

Tab bar controller not appearing correctly

I'm trying to connect Tab Bar Controller to existing part of my app, but when I do that it's "malfunctioning".
However when I run Tab Bar Controller part standalone as initial view controller it works properly like in the image below :
This is how app looks when it is run(correct behavior) :
However when I go to this tab bar controller from my main app this is how it looks like this:
My main app looks like this :
Scroll View contains
UIView 1
UIView 2
UIView 3
UIView x
Each view does something not related to this tab bar controller. Only one view view x tries to "visit" tab bar controller and display some data there, but it's not. Any ideas?
I have this tab bar controller identifier set to test, and I here is how I do that from my view x :
UITabBarController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"test"];
[self.view addSubview:newViewController.view];
EDIT :
Entire app :
I'm creating views programatically. That's why I don't have any relationships/segues to the tab bar controller.
SOLUTION :
Change :
UITabBarController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"test"];
[self.view addSubview:newViewController.view];
To :
UITabBarController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"test"];
[self addChildViewController:newViewController];
[self.view addSubview:newViewController.view];
You need to set a root viewController to the navigation Controller
Just don't do this. From the Apple UITabBarController referenece
Because the UITabBarController class inherits from the UIViewController class, tab bar controllers have their own view that is accessible through the view property. 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.
As I understand it means you must use UITabBarController only as a root view controller of the window. But you can alway use a general UIViewController and add UITabBar there.
(The view offset problem you've met is possible to be fixed, it will not follow the Apple guidelines however and not advised).

Access viewcontroller which resides inside a Tab Bar

I'm trying to access it in my AppDelegate by doing this
Course *rootController = (Course *)[navigationController tabcontroller];
but it won't work doesnt seem to get the "Course" root controller.
Thanks
It is not clear from your question how you have your views arranged and what you are trying to achieve. Usually a UITabBarController contains an array of root view controllers. Each view controller corresponding to a tab on the tab bar. Any or all of those view controllers could be a UINavigationController which itself can contain a stack of view controllers.
UITabBarController
|-UINavigationController -> [AViewController,.....]
|-UINavigationController -> [AnotherViewController,.....]
|-UINavigationController -> [AndAnotherViewController,.....]
The navigation controllers which in this case would be the root view controller for each tab can be accessed via the UITabBarController viewControllers property:
NSArray *rootViewControllers = [tabBarController viewControllers];
So if you want the root view controller of the first tab bar:
UINavigationController *rootViewController = [rootViewControllers objectAtIndex:0];