Adding UITabBarItem to a UITabBar in a UIViewController - iphone

So I have a UIViewController that has a UITabBar in the view. I want to pull down JSON and decided what tabs I want to add to the tab bar, so I need to be able to choose the tabs on runtime. I wanted to use the UITabBarController setViewControllers:animated: method to add to it a list of view controllers. However since I am doing this in a view controller I do not know how to gain access to the tab bar's view controller. Here is my code ...
Header
#import <UIKit/UIKit.h>
#interface HealthTicketTabController : UIViewController <UITabBarDelegate, UITabBarControllerDelegate> {
NSArray *viewControllers;
IBOutlet UITabBar *tabBar;
UIViewController *selectedViewController;
// How do I link this the the tabBar's view controller???
UITabBarController *tabBarController;
}
#property (nonatomic, retain) NSArray *viewControllers;
#property (nonatomic, retain) IBOutlet UITabBar *tabBar;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#property (nonatomic, retain) UIViewController *selectedViewController;
#end
Source
- (id)init
{
self = [super initWithNibName:#"HealthTicketTabView" bundle:nil];
if (self)
{
//Controllers for the tab view
HealthCardController *card = [[HealthCardController alloc] init];
MedicalExpensesController *medical = [[MedicalExpensesController alloc] init];
//Tab bar items to be displayed in the tab bar
card.tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemMostViewed tag:0];
medical.tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemMostViewed tag:1];
NSArray *array = [[NSArray alloc] initWithObjects:card, medical, nil];
//Set the tab bar's view controllers to the list
tabBarController.viewControllers = [NSArray arrayWithObjects:card, medical, nil];
[array release];
[card release];
[medical release];
}
return self;
}

UIViewController has a tabBarController property already. You do not need one in your header file. This is how you can access the UITabBarController.

Found out that since I was using a UIViewController to control the UITabBar I need to set the tab bar's delegate to the current UIViewController and handle the tab events in the current controller.
Adding TabBarItems to the TabBar
[self.tabBar setItems: tabBarItems animated:TRUE];
Switching between ViewControllers
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
UIViewController *temp = [viewControllers objectAtIndex:item.tag];
[self.selectedViewController.view removeFromSuperview];
[self.view addSubview:temp.view];
self.selectedViewController = temp;
}

Related

UI is not updating while sending data from another view controller on UITabBar?

i am using UITabBar to display two viewControllers, firstViewController is a uiview and secondViewController is a table view. what my need is when i clicked the second view table cell, the value should be updated on UILabel of firstViewController.
my code is here,
In secondviewcontroller.h
#interface firstviewcontroller {
NSMutableArray *stationnamestobepassed;
}
#property (nonatomic, retain) NSMutableArray *stationnamestobepassed;
#end
In secondviewcontroller.m declare this
#implementation firstviewcontroller
#synthesize stationnamestobepassed;
-(void) someaction{
stationnamestobepassed = [NSMutableArray
arrayWithObjects:#"string1",#"string2",#"string3"];
secondviewcontroller = [[secondviewcontroller alloc]initWithNibName:#"NIbName"
Bundle:nil];
secondviewcontroller.stationnamespassed = self.stationnamestobepassed;
//i am not pushing the view controller.
}
#end
In firstviewcontroller.h declare this
#interface secondviewcontroller {
NSMutableArray *stationnamespassed;
}
#property (nonatomic, retain) NSMutableArray *stationnamespassed;
#end
In firstviewcontroller.m declare this
#implementation secondviewcontroller
#synthesize stationnamespassed;
-(void)viewWillAppear:(BOOL)animated
{
//stationNameDisplay is a uilabel
stationNameDisplay.text=[stationnamespassed objectAtIndex:0];
NSLog(#"station name %#",[stationnamespassed objectAtIndex:0]);
}
-(void) dealloc{
[stationnamespassed release];
[super release];
}
#end
problem is , value is not updating and it gives NULL. but i tried with pushing the first vie and it works. actually i don't want to push that view controller because i was already exist on tab.
your view will appear called out when you select the tab. while this line makes a new object of that controller, not that of tab controller.
secondviewcontroller = [[secondviewcontroller alloc]initWithNibName:#"NIbName"
Bundle:nil];
to do what you want. you will have to do some thing like this
UINavigationController* navController = [[self.tabBarController viewControllers] objectAtIndex:/*your tab index on which desiredControllerResides*/];
NSArray* viewControllers= [navController viewControllers];
for(UIViewController *theController in viewControllers)
{
if([theController isKindOfClass:[secondviewcontroller]])
{
theController.stationnamespassed = self.stationnamestobepassed;
//i.e this line of your code secondviewcontroller.stationnamespassed = self.stationnamestobepassed;
}
}

Problem in pushing a view controller into a navigationController

I need some help. In my Iphone App I have done something like this :
.
When Distance is selected, I need to show up another view like this:
Here is how I did it:
in the header file
#interface RecherchePartenaireViewController : UIViewController <UINavigationControllerDelegate>
{
UINavigationController *navigationController;
UITableView *tableViewRecherchePartenaire;
RecherchePartenaireTypePartenaireViewController *recherchePartenaireTypePartenaireViewController;
RecherchePartenaireDistanceViewController *recherchePartenaireDistanceViewController;
}
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
#property (nonatomic, retain) IBOutlet UITableView *tableViewRecherchePartenaire;
#property (nonatomic, retain) IBOutlet RecherchePartenaireTypePartenaireViewController *recherchePartenaireTypePartenaireViewController;
#property (nonatomic, retain) IBOutlet RecherchePartenaireDistanceViewController *recherchePartenaireDistanceViewController;
#end
in the implementation file
- (void)viewDidLoad
{
listData = [[NSMutableArray alloc] initWithObjects:#"Type de Partenaire", #"Code postal", #"Ville",#"Distance",#"Nom du Partenaire",#"Audi R8 uniquement",nil];
NSLog(#"hey %#",listData);
tableViewRecherchePartenaire.backgroundColor = [UIColor clearColor];
navigationController=[[UINavigationController alloc] init];
CGRect newRect = navigationController.view.frame;
newRect.size.height -= [UIScreen mainScreen].applicationFrame.origin.y;
[navigationController.view setFrame:newRect];
[navigationController setNavigationBarHidden:YES];
[super viewDidLoad];
}
When the third row of the table is selected I do this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row==3){
NSLog(#"RecherchePartenaireDistanceViewController...");
recherchePartenaireDistanceViewController = [[RecherchePartenaireDistanceViewController alloc] init];
recherchePartenaireDistanceViewController.recherchePartenaireViewController=self;
[self.navigationController pushViewController:recherchePartenaireDistanceViewController animated:YES];
}
}
Please tell me where am I going wrong cause this doesn't seem to work.Thank you.
The approach would be to have a navigationController object with the first tableView as its rootViewController. On the didSelectRowAtIndexPath: method proceed as you do right now. That will push the detailViewController. And in your rootViewController, hide the navigation bar.
Moving from comments to here.
You should add navigation controller to your root view or you won't be able to call method pushViewConroller:.
For example, you can create root view controller in such manner:
RootViewController *controller = [[RootViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
[controller release];
You can push navigation controller, for example, in a such way:
[self presentModalViewController:navController animated:YES];

Adding a TableViewController to an existing project

I have an existing TableViewController as follows
// TableViewController.h
#interface TableViewController : UITableViewController { NSArray *dataArray; }
#property (nonatomic, retain) NSArray *dataArray;
And a navAppDelegate - to be specific:
// navAppDelegate.h
#import <UIKit/UIKit.h>
#interface navwAppDelegate : NSObject
<UIApplicationDelegate, UINavigationControllerDelegate> {
UIWindow *window;
IBOutlet UINavigationController *navigationController;}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) UINavigationController *navigationController;
// navAppDelegate.m
#import "navAppDelegate.h"
#implementation navigationtableviewAppDelegate
#synthesize window, navigationController;
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
[window makeKeyAndVisible];
[window addSubview:[navigationController view]];
}
Now, I simply added the files to an existing project, except I put the content of (void)applicationDidFinishLaunching{} in a (void)viewDidLoad{} since it's a view from now on and not a window (right?). It doesn't work and my guess is that I have to change all the window calls from above to a view? What am I making here fundamentally wrong?
I'm making a call from
// StartOffHere.m
- (void)LetsGoButtonTouched {
navAppDelegate *newview = [[navAppDelegate alloc] initWithNibName:nil bundle:nil]; // I get a SIGABRT here
[[self navigationController] pushViewController: newview animated: YES];
}
- (void)LetsGoButtonTouched {
TableViewController *tableViewController = [[TableViewController alloc] init];
[[self navigationController] pushViewController:tableViewController animated: YES];
}
Try that. Is that what you wanted to happen?
If so, what I have done is created a new instance of your table view controller and pushed that. In your original code, you were trying to push on the app delegate which cannot be done; the app delegate is not a view controller. TableViewController, your subclass of UITableViewController, is though, so you can use this for the pushViewController: method - and the table view will appear on screen.
Thanks Benjamin. Excellent. But it didn't work quite that way though - after two hard days I managed it to run. For those who are interesed, here's what I did:
If you want to add an existing TableViewController with a NavigationController you'll only need the TableViewController and the DetailViewController files. Forget the AppDelegate.
Do twice new file -> Subclass and copy your existing code into identical TableViewController .h/.m/.xib - and DetailViewController .h/.m/.xib respectively.
When you make the method call you have to integrate both the TableViewController and the NavigationController - like this:
- (void)LetsGoButtonTouched {
TableViewController *tvc = [[[TableViewController alloc] init] autorelease];
UINavigationController *navigationController = [[[UINavigationController alloc] initWithRootViewController:tvc]autorelease];
[self presentModalViewController:navigationController animated:YES];
By the way, this question gave me the hint:
Add a UINavigationBar to a UITableViewController without a UINavigationController

Calling method from another class

To begin, I would like to apologize for my English :)
I have FirstViewController, which contains scrollView. This is scrolView with enabled paging, and have 2 pages with 2 different view controllers. From one of the view controllers by touching the button the third view controller appears like a modal view. I call a method in FirstViewController that must disable scrolling and hide two labels which is not contained in the scrollView.
Method is executing, but UI not changes, scrolling still enabled and labels still visible.
Now a bit of code:
This is a piece of the FirstViewController.h (not the whole code):
#interface FirstViewController : UIViewController <UIScrollViewDelegate> {
IBOutlet UIScrollView *scrollView;
IBOutlet UILabel *label1;
IBOutlet UILabel *label2;
}
#property (nonatomic, retain) UILabel *label1;
#property (nonatomic, retain) UILabel *label2;
#property (nonatomic, retain) UIScrollView *scrollView;
-(void)prepareToModal;
#end
Now it's -(void)prepareToModal; implementation:
-(void)prepareToModal {
[label1 setHidden:YES];
[label2 setHidden:YES];
scrollView.scrollEnabled = NO;
}
So, from the one of the view controllers, which contained in scrollView, I call prepareToModal
Previously:
#import "FirstViewController.h"
Next:
FirstViewController *vc = [[FirstViewController alloc] init];
[vc prepareToModal];
[vc release];
So, that's all. I put a breakpoint in prepareToModal, and it stopped executing. The method is called, but nothing changes on screen...
What am I doing wrong?
How to do this correctly?
Update:
I solved this problem.
When I present this modal view, I wrote this:
ThirdViewController *tvc = [[ThirdViewControler alloc] init];
tvc.delegate = self;
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:tvc];
[self presentModalViewController:nc animated:YES];
[tvc release];
[nc release];
Now, insted of [self presentModalViewController:nc animated:YES]; I write this:
[[[[UIApplication sharedApplication].windows objectAtIndex:0] rootViewController] presentModalViewController:nc animated:YES];
And It's working very well, I don't need a method -(void)prepareToModal;
Thanks a lot :)
Make sure you have hooked up your IBOutlets in Interface Builder.

How can I add 2 UITableView on 1 nib/UIView but using 2 different UITableViewController to handle?

How can I add 2 UITableView on 1 nib/UIView but using 2 different UITableViewController to handle ?
Thanks for helping!
Updated:
I understand the basic idea, but I just can't get it working together.
Maybe it is a simple question, but for someone doesn't know, it is obviously a difficult one.
Anyone can help trouble shooting a little bit?
I created a view based application named "MutiTableView",then drag & drop 2 TableView into the nib.
This is the generate ViewController, I add 2 IBOutlet in order to connect with 2 tables in the nib.
#class FirstTableViewController;
#class SecondTableViewController;
#interface MutiTableViewViewController : UIViewController {
UITableView *tablefirst;
UITableView *tablesecond;
FirstTableViewController *firstController;
SecondTableViewController *secondController;
}
//#property (nonatomic, retain) IBOutlet Table1ViewController *viewController;
#property (nonatomic, retain) IBOutlet UITableView *tablefirst;
#property (nonatomic, retain) IBOutlet UITableView *tablesecond;
#property (nonatomic, retain) FirstTableViewController *firstController;
#property (nonatomic, retain) SecondTableViewController *secondController;
This is how I set the datasource and delegate
- (void)viewDidLoad {
NSLog(#"viewDidLoad :(");
firstController = [[FirstTableViewController alloc] initWithStyle:UITableViewStylePlain];
secondController = [[SecondTableViewController alloc] initWithStyle:UITableViewStylePlain];
tablefirst.delegate = firstController;
tablefirst.dataSource = firstController;
tablesecond.delegate = secondController;
tablesecond.dataSource = secondController;
[super viewDidLoad];
}
This is my FirstTableViewController, it is just a basic tableViewController
#interface FirstTableViewController : UITableViewController {
NSArray *listData;
}
#property (nonatomic,retain) NSArray * listData;
#end
#import "FirstTableViewController.h"
#implementation FirstTableViewController
#synthesize listData;
/*
- (id)initWithStyle:(UITableViewStyle)style {
// Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
if (self = [super initWithStyle:style]) {
}
return self;
}
*/
- (void)viewDidLoad {
NSLog(#"FirstTableViewController viewDidLoad");
NSArray * array = [[NSArray alloc] initWithObjects:#"111",#"222",#"333",#"444",#"555",#"666",#"777",#"888",#"999",#"000",nil];
self.listData = array;
[array release];
[super viewDidLoad];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
.....
I also implemented the methods like following.
numberOfSectionsInTableView
tableView:numberOfRowsInSection:
tableView:cellForRowAtIndexPath:
Set the delegate and datasource to different UITableViewControllers.
AUITableViewController * firstController = [[AUITableViewController alloc] init];
UITableView * table1 = [[UITableView alloc] initWith...];
table1.delegate = firstController;
table1.dataSource = firstController;
[someView addSubview:table1];
[table1 release];
[firstController release];
AnotherUITableViewController * secondController = [[AnotherUITableViewController alloc] init];
UITableView * table2 = [[UITableView alloc] initWith...];
table2.delegate = secondController;
table2.dataSource = secondController;
[someView addSubview:table2];
[table2 release];
[secondController release];
It's not tested, but that's the basic idea.
To do it in interface builder, just connect the DataSource and Delegate connectors to different classes / controllers.