I am using the same ViewController for several different views.
When instantiating the ViewController for a specific view, is there an easy way to specify the tab bar icon via code?
yourViewController.tabBarItem = [[UITabBarItem alloc]
initWithTitle:NSLocalizedString(#"Name", #"Name")
image:[UIImage imageNamed:#"tab_ yourViewController.png"]
tag:3];
The viewControllers are added to the tab bar, so the image and names should be set before the tab bar becomes visible (appDelegate if they are there on app start for instance). After that, you could use the above code to change the icon and text from the loadView or viewDidAppear within that viewController.
Yes. Your UITabBar has a property called items, which is an array of UITabBarItems for each tab bar item. You can create a UITabBarItem using the –initWithTitle:image:tag: constructor to use your own image, or the –initWithTabBarSystemItem:tag: constructor to use a system image.
You can also do this in the AppDelegate, by declaring a UITabBarController iVar and pointing it to the applications tabBarController. You can access the individual titles using the items array. and the setTitle.
#synthesize tabBarController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.tabBarController = (UITabBarController*)self.window.rootViewController;
NSArray* items = [self.tabBarController.tabBar items];
[[items objectAtIndex:0] setTitle:#"Home"];
[[items objectAtIndex:1] setTitle:#"Cool"];
[[items objectAtIndex:2] setTitle:#"Stuff"];
[[items objectAtIndex:3] setTitle:#"Settings"];
return YES;
}
Correct way is : Add this below line in viewDidLoad
[self.tabBarItem setImage:[UIImage imageNamed:#"<Image Name>"]];
to viewcontrollers which are set inside UITabBarController
Related
I'm starting out with learning Table Views. My applications uses a Tab Bar Controller and all the tabs are simple views. I want to add another tab, and put a Table View inside of it..how do i do that?
Thanks a lot!
If I want to add another view controller to a tab bar controller, I usually do something like this:
NSMutableArray *items = [tabBarController.viewControllers mutableCopy];
MyTableViewController *c = [[MyTableViewController alloc] init];
[items addObject:c];
[c release];
tabBarController.viewControllers = items;
[items release];
It depends on how you have created the tab bar controller. If it was designed in IB, then drag another tab bar item over to the main window. I then embed a view controller within the tab bar and assign it to the tableview class in question. The .h file for the class will need to be written:
#interface myClass : UITableViewController <UITableViewDelegate, UITableViewDataSource>
The other method that Apple uses when you first set up a basic tab bar app, handles it programmatically with the app delegate. See:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
for the relevant code.
I'm implementing a split view based application.
I have 3 tabs for 3 root views in my application at the bottom of the left view / root views. For this I added three view controllers to the tabbar in app delegete.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
RootViewController *tab1 = [[RootViewController alloc] init];
DashboardViewController *tab2=[[DashboardViewController alloc] initWithNibName:#"DashboardViewController" bundle:nil];
SendUpdatesViewController *tab3=[[SendUpdatesViewController alloc] initWithNibName:#"SendUpdatesViewController" bundle:nil];
NSArray *tabViewArray=[[NSArray alloc] initWithObjects:tab1,tab2,tab3,tabBar, nil];
tabBar=[[UITabBarController alloc] init];
[tabBar setViewControllers:tabViewArray];
self.splitViewController.viewControllers = [NSArray arrayWithObjects:tabBar,_detailViewController, nil];
self.window.rootViewController = self.splitViewController;
[self.window makeKeyAndVisible];
return YES;
}
Now I need to add titles icons and the corresponding actions for these tabs.
You can assign titles to your viewcontrollers using the title-property. By default these titles are shown in the tabbar. You can also customize the UITabbarItem for each controller. Read more about that here: http://developer.apple.com/library/ios/DOCUMENTATION/UIKit/Reference/UITabBarItem_Class/Reference/Reference.html#//apple_ref/occ/cl/UITabBarItem
A good solution for this would be to overwrite the getters inside your viewcontrollers for the "title" and "tabBarItem" properties, making use of lazy instantiation to make sure the properties are properly set when they are accessed for the first time. This way you also keep this code contained in each viewcontroller's implementation.
I have built my app using Storyboards. I have a UITabBarController and a NavigationController embedded it that.
I am trying to customise my app with tint colors and I have managed to set a custom color for the Tabbar. I was able to access the tabbar from the rootViewController, however I cannot get access to the navigation bar. Is there anyway that I can easily access this?
Sample of my AppDelegate code is below.
Thanks
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
self.tabBarController = (UITabBarController*)self.window.rootViewController;
UITabBar *tabBar = self.tabBarController.tabBar;
[tabBar setSelectedImageTintColor:[UIColor greenColor]];
tabBar.tintColor = [UIColor colorWithRed:0.4 green:0.522 blue:0.129 alpha:1];
//This bit doesnt work
UINavigationController *navCon = self.tabBarController.navigationController;
navCon.navigationBar.tintColor = [UIColor colorWithRed:0.384 green:0.259 blue:0.161 alpha:1];
return YES;
}
If you're using navigation controllers, would expect them to embed the view controllers that are managed by the tab bar controller.
Try NSLog(#"%#", [self.tabBarController viewControllers]); and see whether it lists navigation controllers or your custom controller. For example, I created two view controllers that are triggered by my tab bar, one with and one without navigation and the above line shows:
(
"<UINavigationController: 0x6a35f20>",
"<SecondViewController: 0x6a39500>" )
So, I could get mine as [[self.tabBarController viewControllers] objectAtIndex:0].
Assuming you did no work with IBOutlet's, I suggest you maybe use them along with the XIB file. For example, In the header file:
IBOutlet UINavigationBar *aNavBar;
And then in the .m, switch:
UINavigationController *navCon = self.tabBarController.navigationController;
navCon.navigationBar.tintColor = [UIColor colorWithRed:0.384 green:0.259 blue:0.161 alpha:1];
With:
[aNavBar setTintColor:[UIColor colorWithRed:0.384 green:0.259 blue:0.161 alpha:1]];
And there you go! I made this quick, so tell me if it works or not.
-Justin A.
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.
I have a UITabBarController that manages 5 View Controllers. I create their tab bar items in their "init" methods so that they will be displayed before the view is loaded. I'm just wondering what way I should do it, because there seems to be so many ways. For example, for my DatePickerViewController:
- (id)init {
if((self = [super init])) {
// ================ THIS ==========================
UIImage *clockIcon = [UIImage imageNamed:#"clockicon.png"];
UITabBarItem *localTabBarItem = [[UITabBarItem alloc]
initWithTitle:#"Date" image:clockIcon tag:0];
[self setTabBarItem:localTabBarItem];
[localTabBarItem release];
// ================ OR THIS ========================
[self setTitle:#"Date"];
UITabBarItem *localTabBarItem = [[UITabBarItem alloc] init];
[localTabBarItem setImage:[UIImage imageNamed:#"clockicon.png"]];
[self setTabBarItem:localTabBarItem];
[localTabBarItem release];
// ================ OR THIS ========================
UITabBarItem *localTabBarItem = [[UITabBarItem alloc] init];
[localTabBarItem setTitle:#"Date"];
[localTabBarItem setImage:[UIImage imageNamed:#"clockicon.png"]];
[self setTabBarItem:localTabBarItem];
[localTabBarItem release];
}
return self;
}
Which way should I do it? And why is there a title for both the tabBarItem and the View Controller? And I don't think I need the tag (which is set in the first method).
Thanks!!
Well in my opinion any of these ways are ok, it might be more readible when you declare the UIImage in one line and set it in a different line rather than doing it all inline, but at the end you get the same result.
The TabBarItems have a title which is the text that will show in the tab bar item iteself. View Controllers have a title for Navigation Controller purposes, the View Controllers title is displayed in the NavigationControllers NavBar when set. And you do need tags, tags is the way you tell the buttons apart when someone click on them (when u manage the TabBar on your own).
The reason there are several ways to set the title is for convienece. You may want to display one title in the navigation bar and one title in the tab bar.
This actually quite common since there is less space to display text in the tab bar.
Like many things in Cocoa, there is more than one way to do it. The only "correctness" you need to be concerned about is what works best for your situation.