Reusable TableView header views - iphone

For performance sake it is usual to reuse UITableView' cells.
Is there a way to do the same thing with TableView header' views?
I am talking about the ones that are returned with delegate's method:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
I tried to do the following which doesn't seem to be working as expected:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
static NSString *CellIdentifier = #"Header";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
if (cell == nil) {
cell = [self getHeaderContentView: CellIdentifier];
}
return cell;
}
Is there a way to reuse header' views?

The reason Apple built in the ability to reuse tableview cells is because while the tableview may have many rows, only a handful are displayed on screen. Instead of allocating memory for each cell, applications can reuse already existing cells and reconfigure them as necessary.
First off, header views are just UIViews, and while UITableViewCell is a subclass of UIView, they are not intended to be placed as the view of a section header.
Further, since you generally will have far fewer section headers than total rows, there's little reason to build a reusability mechanism and in fact Apple has not implemented one for generic UIViews.
Note that if you are just setting a label to the header, you can use -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section instead.
For something more custom, such as a label with red text (or a button, image, etc), you can do something like this:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0,0, 320, 44)] autorelease];
UILabel *label = [[[UILabel alloc] initWithFrame:headerView.frame] autorelease];
label.textColor = [UIColor redColor];
label.text = [NSString stringWithFormat:#"Section %i", section];
[headerView addSubview:label];
return headerView;
}

You can implement that by creating UITableViewHeaderFooterView class
it is subclass of UIView
You also need to create an individual XIB as it will not be created automatically with UITableViewHeaderFooterView creation.
Register Nib with tableview
[self.tblCart registerNib:[UINib nibWithNibName:#"CartHeaderView" bundle:nil] forHeaderFooterViewReuseIdentifier:#"CartHeader"];
Now You can Access that in viewForHeaderInSection
-(UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
CartHeaderView *sectionHeader=[tableView dequeueReusableHeaderFooterViewWithIdentifier:#"CartHeader"];
return sectionHeader;
}
Note :
To set background color you will need to create a subview with same frame as section header and set color for that view.
you can follow
Changing the background color on a UITableViewHeaderFooterView loaded from a xib says to use contentView.backgroundColor instead

A simple yet effective solution:
#interface SectionedTableViewController ()
#property (nonatomic, strong) UINib* sectionHeaderNib;
#property (nonatomic, strong) NSMutableArray* sectionHeaders;
#end
#implementation SectionedTableViewController
#synthesize sectionHeaderNib = sectionHeaderNib_;
#synthesize sectionHeaders = sectionHeaders_;
- (void) viewDidUnload
{
self.sectionHeaders = nil;
[super viewDidUnload];
}
- (NSMutableArray*) sectionHeaders
{
if (!sectionHeaders_)
self.sectionHeaders = [NSMutableArray array];
return sectionHeaders_;
}
- (UINib*) sectionHeaderNib
{
if (!sectionHeaderNib_)
self.sectionHeaderNib = [UINib nibWithNibName: NSStringFromClass(YourHeaderView.class) bundle: nil];
return sectionHeaderNib_;
}
- (YourHeaderView*) dequeueHeader
{
return [self.sectionHeaders firstObjectPassingTest: ^(id obj) { return (BOOL) ([obj superview] == nil); }];
}
- (NSString*) sectionHeaderTitleForSection: (NSInteger) section
{
return nil;
}
- (UIView*) tableView: (UITableView*) tableView viewForHeaderInSection: (NSInteger) section
{
YourHeaderView* headerView = [self dequeueHeader];
if (!headerView)
{
headerView = [YourHeaderView instanceFromNib: self.sectionHeaderNib];
[self.sectionHeaders addObject: headerView];
}
return headerView;
}
#end

Related

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.

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.

Iphone programming: Multiple UITableViews reading from the same source?

This question is related to UITableView issue when using separate delegate/dataSource, though I have a different problem. I'm just starting to learn iPhone programming.
Basically I have one main view with a table. On the event of a cell click, a sub view with another table is shown.
The datasource and delegate for the main view's table are set as files' owner, and I have added the necessary code in there to handle the table data and everything is fine.
But, when the second table in the sub-view seems to crash the application, I did the same thing, set the datasource and delegate to the file's owner and repeated the same procedure as for the main view's table. I have no idea why this is happening.
The sub-view has its only nib/xib file and its own outlet. If i do not attach any datasource to the subview's table, it takes the data from the main view's table; I don't understand why that is, since I have set the datasource to be the file's owner.
For example: the FirstView controller has a table FirstTable, the datasource and delegate are set to the owner of Files. I added the following in FirstView.m:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 4;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"LibraryListingCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text =#"Table Cell";
return cell;
}
Everything works perfectly.
The moment I repeat this with a second table and a second view, the application crashes saying
reason: '-[UISectionRowData tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x69188d0'
I have done exactly the same for second table: implemented numberOfRowsInSection and cellForRowAtIndexPatch inside secondview.m and set the second table's delegate and datasource to the file's owner. If I remove the delegate and datasource for the second table, the application doesn't crash but has an empty table in the second view.
Any suggestions? or am I missing some key concept here ?
You can use same datasource and delegate methods for multiple tables.
You have to mention in which table you are doing operations.
For example:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([tableView isEqual:TableView1])
{
//do work for tableview1
}
else if([tableView isEqual:TableView2])
{
//do operations for tableview2
}
}
This is the main View controller .h file.
#import <UIKit/UIKit.h>
#import "SubView.h"
#interface StackOverTableSubViewViewController : UIViewController <UITableViewDelegate,UITableViewDataSource>
{
UIView *contentView;
UITableView *tblVw;
NSMutableArray *array;
SubView *SubViewObj;
}
#property(nonatomic,retain) UIView *contentView;
#property(nonatomic,retain) UITableView *tblVw;
#property(nonatomic,retain) NSMutableArray *array;
#property(nonatomic,retain) SubView *SubViewObj;
#end
This is the main View controller .m file.
#import "StackOverTableSubViewViewController.h"
#implementation StackOverTableSubViewViewController
#synthesize contentView,tblVw,array,SubViewObj;
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
contentView=[[UIView alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
contentView.autoresizingMask=(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
contentView.autoresizesSubviews=YES;
contentView.backgroundColor=[UIColor whiteColor];
tblVw=[[UITableView alloc]initWithFrame:[[UIScreen mainScreen]bounds] style:UITableViewStylePlain];
tblVw.dataSource=self;
tblVw.delegate=self;
tblVw.scrollEnabled=YES;
array=[[NSMutableArray alloc]init];
[array addObject:#"Row1"];
[array addObject:#"Row2"];
[array addObject:#"Row3"];
[array addObject:#"Row4"];
[array addObject:#"Row5"];
[array addObject:#"Row6"];
[array addObject:#"Row7"];
[array addObject:#"Row8"];
[array addObject:#"Row9"];
[array addObject:#"Row10"];
[array addObject:#"Row11"];
[array addObject:#"Row12"];
[contentView addSubview:tblVw];
self.view=contentView;
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
return [array count];
}
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
// Dequeue or create a cell of the appropriate type.
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;
[cell.textLabel sizeToFit];
}
cell.textLabel.text=[array objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SubViewObj=[[SubView alloc]init];
[self.view addSubview:SubViewObj.view];
}
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[contentView release];
[SubViewObj release];
[tblVw release];
[array release];
[super dealloc];
}
#end
Add a view controller called subview. Here's subview.h:
#import <UIKit/UIKit.h>
#interface SubView : UIViewController <UITableViewDelegate,UITableViewDataSource>
{
UIView *contentView;
UITableView *tblVw;
NSMutableArray *array;
}
#property(nonatomic,retain) UIView *contentView;
#property(nonatomic,retain) UITableView *tblVw;
#property(nonatomic,retain) NSMutableArray *array;
#end
And subview.m:
#import "SubView.h"
#import
#implementation SubView
#synthesize contentView,tblVw,array;
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
contentView=[[UIView alloc]initWithFrame:CGRectMake(200, 10, 300, 600)];
contentView.autoresizingMask=(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
contentView.autoresizesSubviews=YES;
contentView.backgroundColor=[UIColor whiteColor];
tblVw=[[UITableView alloc]initWithFrame:CGRectMake(200, 10, 300, 600) style:UITableViewStylePlain];
tblVw.dataSource=self;
tblVw.delegate=self;
tblVw.scrollEnabled=YES;
tblVw.layer.borderWidth=4.0;
tblVw.layer.borderColor=[[UIColor redColor]CGColor];
array=[[NSMutableArray alloc]init];
[array addObject:#"Data1"];
[array addObject:#"Data2"];
[array addObject:#"Data3"];
[array addObject:#"Data4"];
[array addObject:#"Data5"];
[array addObject:#"Data6"];
[array addObject:#"Data7"];
[array addObject:#"Data8"];
[array addObject:#"Data9"];
[array addObject:#"Data10"];
[array addObject:#"Data11"];
[array addObject:#"Data12"];
[contentView addSubview:tblVw];
self.view=contentView;
}
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
return [array count];
}
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
// Dequeue or create a cell of the appropriate type.
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;
[cell.textLabel sizeToFit];
}
cell.textLabel.text=[array objectAtIndex:indexPath.row];
return cell;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
Try this code. This app was done for the iPad. Change the dimensions as needed for the iPhone.
I had the EXACT same issue and fixed it by deleting my connection from the table view's datasource to the files owner. Then I pasted in the code below replacing the existing cellForRowAtIndexPath. I had to change the array name to match my array and then reconnect the datasource to the files owner, and it started working. Must have been a snafu in my function code somewhere.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
// Dequeue or create a cell of the appropriate type.
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;
[cell.textLabel sizeToFit];
}
cell.textLabel.text=[array objectAtIndex:indexPath.row];
return cell;
}

UITableView as a subview?

Is this possible? I just want a small table in my current view... here is what I'm trying to do:
.h file
#import <UIKit/UIKit.h>
#interface IngredientsRootView : UIViewController <UITableViewDelegate, UITableViewDataSource> {
UITableView *ingredientsTable;
}
#property (nonatomic, retain) UITableView *ingredientsTable;
#end
.m file I have delegate and data source methods and this code:
ingredientsTable = [[UITableView alloc] initWithFrame:CGRectMake(10, 10, 300, 300) style:UITableViewStylePlain];
[ingredientsTable setDelegate:self];
[ingredientsTable setDataSource:self];
[self.view addSubview:ingredientsTable];
The app doesn't crash, but it doesn't show a table. At the moment I have just set everything definitely as per:
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return 10;
}
// the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
cell.textLabel.text = #"Hello";
return cell;
}
What am I doing wrong? Thanks
Try calling -reloadData on the table view after adding it as a subview.
Also, how is the view set up? Is it created in a XIB or via -loadView?
Did you remembered to add the [window addSubview:[IngredientsRootView view]]; to your app delegate ?
And by the way, instead of inheriting from UIViewController you can just inherit from UITableViewController and you'll get all that functionality for you with no added code.

having two table views in a single xib one of plain style and the other grouped styled

I want to use two tableviews under the segmentedcontrol. one is plain styled and the other is groupstyled. How can i controll the delegate and datasource for the two table views?
--
Regards,
Syed yusuf
HI,
I have to inserted the data into table view by using sqlite.But now i need that data in to two table views in next view..I have arranged segmented bar.Am getting two table views but the values in r not displaying.It is displaying NULL.
Using multiple or two exclusive table in the save UI view controller sharing the same data source.
I face a problem like this, if anybody needs later...
I try to set my ViewController as a datasource for two different table. But it did not work. 2 tables are exclusively shown at loadtime of the view. Either one will be hidden in viewDidLoad depending on a flag. Seems once dataSource is called for one table, it's not called for the 2nd table. All connections are set in IB.
The solution is to set the dataSource in code in viewDidLoad. Then it works.
-(void) viewDidLoad(){
table1.dataSource = self;
table2.dataSource = self;
if(someCondition == YES)
table1.visible = NO;
else
table2.visible = NO;
}
Since you can't change the UITableViewStyle of a UITableView once created (it can only be set at construction time), you have to have two different instances. You can do this in very different ways, but I've done it this way: add a UISegmentedControl to your interface, and set its target to the RootViewController class instance in your application. The RootViewController class could look like this:
#class DataSource;
#interface RootViewController : UITableViewController
{
#private
UITableView *_originalTableView;
UITableView *_secondaryTableView;
DataSource *_dataSource;
BOOL _showingSecondaryTableView;
}
- (IBAction)swap:(id)sender;
#end
And this might be the implementation:
#import "RootViewController.h"
#import "DataSource.h"
#implementation RootViewController
- (void)dealloc
{
[_dataSource release];
[_originalTableView release];
[_secondaryTableView release];
[super dealloc];
}
- (void)viewDidLoad
{
[super viewDidLoad];
_dataSource = [[DataSource alloc] init];
_secondaryTableView = [[UITableView alloc] initWithFrame:self.tableView.frame
style:UITableViewStyleGrouped];
_secondaryTableView.delegate = _dataSource;
_secondaryTableView.dataSource = _dataSource;
_originalTableView = [self.tableView retain];
_showingSecondaryTableView = NO;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark -
#pragma mark IBAction method
- (IBAction)swap:(id)sender
{
if (_showingSecondaryTableView)
{
self.tableView = _originalTableView;
_showingSecondaryTableView = NO;
}
else
{
self.tableView = _secondaryTableView;
_showingSecondaryTableView = YES;
}
}
#pragma mark -
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [NSString stringWithFormat:#"RootViewController cell %d", indexPath.row];
return cell;
}
#end
This is the interface of the DataSource class:
#import <UIKit/UIKit.h>
#interface DataSource : NSObject <UITableViewDelegate,
UITableViewDataSource>
{
}
#end
And the implementation:
#import "DataSource.h"
#implementation DataSource
#pragma mark -
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"DataSourceCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [NSString stringWithFormat:#"DataSource cell %d", indexPath.row];
return cell;
}
#end
You can change the datasource and delegate of the UITableView instances to anything you want, at any time during runtime, which might help you encapsulate different data sources with separate controllers.
Hope this helps!