Multiple UITableview Index bars - iphone

I am adding two UITableViews to my view in my code. I am properly setting the delegates and datasource to self. I have added all the delegate methods for returning the number of row, height for row, number of sections etc. And everything is working fine. I have also added index bars to both tables. Now the problem is the index bar is not working for the 1st table, while it is working fine for the second table.
When I click on any character on 1st tables index bar, it responds for the 2nd table. I am not able to get the action for the 1st Table. I also noticed that if I don't add the second table to my view, then I am able to get the action for the 1st table.
Here is my code
- (void)viewDidLoad
{
accountsTable = [[UITableView alloc] initWithFrame:CGRectMake(0,27, 320, 390) style:UITableViewStylePlain];
[accountsTable setDelegate:self];
[accountsTable setDataSource:self];
[self.view addSubview:accountsTable];
accountsTable.backgroundColor = [UIColor clearColor];
[accountsTable release];
keyConnectionsTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 27, 320, 390) style:UITableViewStylePlain];
[keyConnectionsTable setDelegate:self];
[keyConnectionsTable setDataSource:self];
[keyConnectionsTable setBackgroundColor:[UIColor clearColor]];
[keyConnectionsTable setHidden:YES];
[self.view addSubview:keyConnectionsTable];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return [NSArray arrayWithArray:[[UILocalizedIndexedCollation currentCollation] sectionIndexTitles]];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex:index];
}

You need to differentiate both table views. To do this you could simply use the "tag" property and set it to different values, or you could have a #property in your view controller for each TableView.
#property (strong) IBOutlet UITableView *tv1;
#property (strong) IBOutlet UITableView *tv2;
For your methods, you could do something like:
- (NSInteger)numberOfSectionsInTableView:(UITableView *) tableView {
if (tableView == self.tv1) {
return 1;
} else if (tableView == self.tv2) {
return 2;
}
}
Bottom Line
You need to differentiate both TableViews or you're going to make a mess :)

Related

TableView wont display provided data

I am having a strange issue with TableView. Here is some code to clarify everything:
I am using tabbed panes and this right here is just one of my two ViewControllers:
As you can see, all I do is setting up an UIView and placing a tableView right ontop of it.
#import "SuchenCtrl.h"
#interface SuchenCtrl ()
#end
#implementation SuchenCtrl
#synthesize MainView;
#synthesize Standort;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view = self.MainView;
[self.Standort.tableView setDelegate:self.Standort];
[self.Standort.tableView setDataSource:self.Standort];
[self.MainView addSubview:self.Standort.tableView];
}
- (id)init {
self = [super init];
if(self) {
CGRect rect = [[UIScreen mainScreen] applicationFrame];
self.MainView = [[UIView alloc] initWithFrame:rect];
[self.MainView setBackgroundColor:[UIColor blackColor]];
//Alloc UITableViewController
self.Standort = [[UIStandort alloc] initWithStyle:UITableViewStylePlain];
[self.Standort release];
[self.MainView release];
}
return self;
}
#end
Now UIStandort is another class that simply inherits from UITableViewController. It implements all necessary functions to display data. All im trying to achieve is having the table display "Test" a couple of times but it wont. The table gets displayed nicely but just with empty cells. When I breakpoint one of the implemented functions in the class UIStandort nothing gets called, so my assumption is that the delegate and sourceData are pointing to wrong classes? Though, I explicitly assign those before putting the table on the view.
UIStandort* Standort is declared with properties retain and nonatomic if this helps.
#import "UIStandort.h"
#interface UIStandort ()
#end
#implementation UIStandort
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 0;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath(NSIndexPath *)indexPath
{
UITableViewCell* cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
cell.textLabel.text = #"Test";
[cell autorelease];
return cell;
}
#end
Thanks.
You return 0 for the number of row in section. The documentation states:
The number of sections in tableView. The default value is 1.
Can you try:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}

TableView is not loading data?

In my Map application I have segment controller on main screen and using that I have Map View & tableview(both are UIView). I have tried everything but my data is not loading in my tableview. Here is my tableview code. Here marker is attribute in my xml file which contain Showroom name and Iam able to parse this.
.h file
#interface HViewController : UIViewController<UITableViewDataSource, UITableViewDelegate> {
UITableView *_tableView;
}
#property (nonatomic, retain) IBOutlet UITableView *_tableView;
#end
.m file
Edited = with ViewWillAppear,viewDieLoad, segement action method
#synthesize tableView;
- (void)viewDidLoad {
appDelegate = (HAppDelegate *)[[UIApplication sharedApplication] delegate];
[segmentedControl addTarget:self action:#selector(segmentAction:)
forControlEvents:UIControlEventValueChanged];
}
- (void)viewWillAppear:(BOOL)animated
{
self._tableView.rowHeight = 80.0;
[_tableView reloadData];
}
-(void)segmentAction:(id)sender;{
UISegmentedControl* segCtl = sender ;
if( [segCtl selectedSegmentIndex] == 0 )
{
NSLog(#"segmentAction mapView");
mapView.hidden = NO;
_tableView.hidden = YES;
//[ self.view addSubview:mapView] ; // adding view to segmentindex 0
}
if( [segCtl selectedSegmentIndex] == 1 )
{
NSLog(#"segmentAction _tableview");
_tableView.hidden = NO;
mapView.hidden = YES;
//[ self.view addSubview:_tableview] ;
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"appDelegate.markers _tableview");
return [appDelegate.markers count];
}
//method to print row(showroom count on Header)
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection: (NSInteger)section {
if(section == 0)
return [NSString stringWithFormat:NSLocalizedString(#"ShowRooms[%d]", #"Showroom format"), [appDelegate.markers count]];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath {
static NSUInteger const kShowroomNameLabelTag = 2;
UILabel *ShowroomNameLabel = nil;
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
ShowroomNameLabel = [[[UILabel alloc] initWithFrame:CGRectMake(50, 1, 300, 20)] autorelease];
ShowroomNameLabel.tag = kShowroomNameLabelTag;
ShowroomNameLabel.font = [UIFont boldSystemFontOfSize:18];
[cell.contentView addSubview:ShowroomNameLabel];
NSLog(#"UITableViewCell.markers _tableview");
}
else
{
ShowroomNameLabel = (UILabel *)[cell.contentView viewWithTag:kShowroomNameLabelTag];
}
marker *aMarker = [appDelegate.markers objectAtIndex:indexPath.row];
//ShowroomNameLabel.text = aMarker.name;
ShowroomNameLabel.text= [NSString stringWithFormat:#"ShowroomName= %#", aMarker.name];
return cell;
}
In my tableview Header it shows data count correctly but not showing data.
I have connected delegate,datasource,_tableview to fileOwner of the HViewController in which I have put above code. Plz suggest something where I am wrong. I am parsing XML file and getting data in console alos I can show it on Map. But I am not able to load data in my tableview.
Try moving [_tableView reloadData] to viewWillAppear.
UITableViewController reloads the table view's data in viewWillAppear, not viewDidLoad. I can't tell you the exact reason for which this would make a difference, though I can think of several. Anyway, it's worth a try.
EDIT:
RESPONSE TO COMMENTS
If titleForHeaderInSection: is being called, then there is a data source connected to a table view. So, the problem is not a lack of a data source connection.
I am guessing you have 2 table views in your .xib file: a large one & a short one below it. The large table view is not connected to the data source, so it just displays blank lines. The short table view is connected to the data source. But, it is just tall enough for a header and has no space left to display any cells. Thus, titleForHeaderInSection: is called, but cellForRowAtIndexPath: is not because there is no space to display any cells.
Note that this is just a guess, but it is the only scenario I can think of that would cause the behavior you described. The code you posted looks ok, although a bit more complicated than necessary.
There is no question that reloadData should be in viewWillAppear. That's where the Apple engineers put it when they created the UITableViewController class. So, to put it elsewhere, you have to believe you know better than they do.

Managing two tableviews in a single class

How to access two or more tableViews in a single class with tabledatasource and tabledelegates?
In a same delegate method you have to handle all tableviews,
For ex:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(tableView==tableView1)
//value for first tableview
else if(tableview==tableView2)
//value for second tableview
}
If you are adding them from XIB then answer from KingofBliss is right one, otherwise if you are adding them programmatically you can set tag property on them and then in delegate use it to distinguish which table are you working on.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if([tableView tag] == 1)
{
//value for first tableview
} else {
//value for second tableview
}
UITableView tableView1 = [[UITableView alloc] init];
when you create tableview give tag to them..
tableView1.tag = 10;
tableView1.delegate = self;
tableView1.dataSource = self;
[self.view addSubview:tableView1];
[tableView1 release];
UITableView tableView2 = [[UITableView alloc] init];
tableView2.tag = 20;
tableView2.delegate = self;
tableView2.dataSource = self;
[self.view addSubview:tableView2];
[tableView2 release];
And in delegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(tableView.tag == tableView1.tag)
//value for first tableview
else if(tableview.tag==tableView2.tag)
//value for second tableview
}
I don't think so there is necessary to add two UITableViews and differentiate them, because same delegate functions are going to be called. Just add one UITabaleView and perform check on your data, set flags, for example if currently your UITableView is filled with Array1 and now you want to to fill it with Array2 just set flag and call [UITableView reloadData].
Your problem solved.
As for as i suggest, adding two UITableViews in same class is not good practice

NSMuttableArray,TableView , Switch Views Programmatically

I am a new Programmer of Iphone..... i have a little problem in accessing the NSMuttable array in my programe...
i am generating a view programmatically on button click .... code on button click is
-(IBAction)buttonClicked
{
secondView=[[TabBarSearchSecondView alloc]init];
[myView addSubview:secondView.view];
}
inTabBarSearchSecondView .h file.....
#interface ......
NSMuttableArray *searchResult;
#end
#property (nonatomic,retain)NSMuttableArray *searchResult;
in TabBarSearchSecondView .m file.........
#synthesize searchResult;
- (void)loadView
{
CGRect cgRct = CGRectMake(0.0, 0.0, 480, 320); //define size and position of view
myView = [[UIView alloc] initWithFrame:cgRct]; //initilize the view
//open database
DbOpenAndClose *dbObject=[[DbOpenAndClose alloc]init];
[dbObject openDatabase];
//for call of search showroom
SearchProduct *object=[[SearchProduct alloc]init];
searchResult=[object searchShowrooms:productname:cityname];
[dbObject closeDatabase];
count=[searchResult count];/// print 3 because 3 record match in database
UITableView *table=[[UITableView alloc]initWithFrame:CGRectMake(4,80,312,325) style:UITableViewStylePlain];
//table.delegate=self;
table.dataSource=self;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//NSLog(#"%i", [searchResult count]);
return [searchResult count]; ///Not accessible here...Application Crash Here...
}
thanks for giving your valueable time for my Code...... thanks in Advance
you have to retain the searchResult array....
after this code
searchResult=[object searchShowrooms:productname:cityname];
retain the searchResult. otherwise it is released.. retain the searchResult like this.
[searchResult retain];

UITableView as a tableHeaderView for another UITableView

I get stuck on the following: I want to use a single cell of a UITableView as a header view for another UITableView. The second table view is in turn an object that has been inherited from a different UITableView class, since it shares it's functionality completely. The only difference in fact is that the second UITableView has a header view (which should be the single celled UITableView).
The interface for the UITableView with the header looks like:
#import <UIKit/UIKit.h>
#import "ScheduleDetailsController.h"
#interface TodayDetailsViewController : ScheduleDetailsController <UITableViewDelegate, UITableViewDataSource> {
UITableView *headerView;
}
#property (nonatomic, retain) UITableView *headerView;
#end
And the implementation like:
#import "TodayDetailsViewController.h"
#implementation TodayDetailsViewController
#synthesize headerView;
- (void)loadView {
[super loadView];
self.headerView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
self.headerView.backgroundColor = [UIColor clearColor];
self.headerView.opaque = NO;
self.headerView.delegate = self;
self.headerView.dataSource = self;
// This is a UITableView defined as a property in the parent class
self.scheduleDetailsTable.tableHeaderView = self.headerView;
}
...
#pragma mark -
#pragma mark Table View Data Source Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (tableView == self.scheduleDetailsTable.tableHeaderView)
return 1;
else
return [self.scheduleDetailsTable numberOfSections];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.scheduleDetailsTable.tableHeaderView)
return 1;
else
return [self.scheduleDetailsTable numberOfRowsInSection:section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == self.scheduleDetailsTable.tableHeaderView) {
...
return cell;
} else
return [self.scheduleDetailsTable cellForRowAtIndexPath:indexPath];
}
#end
I get no errors when I compile and run this, but then I also don't see anything, i.e. the view stays empty. I have also tried it with replacing the header view by a UIView and then everything works like expected (i.e. the table view in the parent class is implemented correctly). I'm probably just missing something obvious, but I just can't figure it out at the moment. If someone could spot the error or could give some advice I would be very thankful.
Not for nothing, but do you really need to create a whole UITableViewController and UITableView just to use a UITableViewCell as a header? A UITableViewCell is a subclass of UIView, after all.
This works, more or less, (had to make the labels not opaque myself; I guess the UITableView normally handles that):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UITableViewController *testTableViewController = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
UITableViewCell *tableViewCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:NULL];
tableViewCell.textLabel.text = #"Test";
tableViewCell.textLabel.opaque = NO;
tableViewCell.detailTextLabel.text = #"123";
tableViewCell.detailTextLabel.opaque = NO;
testTableViewController.tableView.tableHeaderView = tableViewCell;
[tableViewCell release];
// self.window is initilized and hooked up in MainMenu.xib
self.window.rootViewController = testTableViewController;
[self.window makeKeyAndVisible];
[testTableViewController release];
return YES;
}
For that matter, if the above wont meet your needs why not just bump everything down in your table view by one section, and use the very top section as the "header":
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return ([super numberOfSectionsInTableView:tableView] + 1);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0) {
return 1;
} else {
return [super tableView:tableView numberOfRowsInSection:(section + 1)];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0) {
// ***** Build and return your header cell *****
} else {
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:(indexPath.section + 1)];
return [super tableView:tableView cellForRowAtIndexPath:newIndexPath];
}
}
Repeat as necessary for all the other data source delegates.
Just a thought...
Well, I solved the problem by replacing the return statements of the delegate methods in my original posting from
return [self.scheduleDetailsTable cellForRowAtIndexPath:indexPath];
to
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
And similarly for the other delegate methods. Now everything works like expected. Thanks to peterjb for using this syntax in his response to my original question.