Iphone programming: Multiple UITableViews reading from the same source? - iphone

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;
}

Related

Table view controller on view controller

I am creating an app in which i want to display a text box and when i enter an word in it ,then it will display the contents from the dictionary which are matching to that word.Now i want to display the list which will generate from my dictionary according to the word entered in text box ,in a table view and that table view should be on the same view controller where i am having the text box.Is it possible to do so. I mean is it possible to create a table view with scrolling option so that user can scroll through the list and then select the word which he wants.
Yes it is possible. Take IBOutlet for UITableView and wire it up. Define its datasource and delegate to your controller. Implement UITableViewDelegate to your controller and override all the methods like cellForRowAtIndex and others.
//FilterDataViewController.h
#import <UIKit/UIKit.h>
#interface FilterDataViewController : UIViewController <UITableViewDelegate>
{
IBOutlet UITableView *tblView;
IBOutlet UITextField *txtFld;
NSMutableArray *arrSrch;
NSMutableArray *srchedData;
}
-(IBAction)srchBtnTapped:(id)sender;
#end
//FilterDataViewController.m
#import "FilterDataViewController.h"
#implementation FilterDataViewController
-(IBAction)srchBtnTapped:(id)sender
{
if(![txtFld.text isEqualToString:#""])
{
[srchedData removeAllObjects];
for (NSString *allStrings in arrSrch)
{
NSComparisonResult result = [allStrings compare:txtFld.text options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [txtFld.text length])];
if (result == NSOrderedSame)
{
[srchedData addObject:allStrings];
}
}
[tblView reloadData];
}
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
arrSrch = [[NSMutableArray alloc] initWithObjects:#"One",#"One Two",#"Two",#"Three",#"Four",#"One Five",#"Six",nil];
srchedData = [[NSMutableArray alloc] init];
}
#pragma mark -
#pragma mark Table view data source
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [srchedData count];
}
// Customize 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];
}
cell.textLabel.text = [srchedData objectAtIndex:indexPath.row];
// Configure the cell.
return cell;
}
#end
This is surely possible. Create a View based Application and put both of your table view and Text Field in the same view and you can do what ever you are planning to do.

Trouble Reloading UITableView

I am trying to create an iphone application that reads a json feed and I am having some trouble updating a TableView.
This is my TableViewController header file:
#interface LiveNewsController : UITableViewController <UITableViewDelegate, UITableViewDataSource>{
NSMutableData *responseData;
NSMutableArray *articleArray;
UITableView *tblView;
}
-(void) refreshPressed: (id)sender;
#property (nonatomic, retain) IBOutlet UITableView *tblView;
#end
These are some parts of my TableViewController implementation file:
#implementation LiveNewsController
#synthesize tblView;
-(id) init {
if(self = [super init])
{
self.title = #"Live News";
}
return self;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"I am here %d",[articleArray count]);
return [articleArray count];
}
// Customize 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];
}
NSLog(#"cellForRowAtIndexPath called. Data size %d", [articleArray count]);
NSUInteger row = [indexPath row];
cell.textLabel.text = [articleArray objectAtIndex:row];
return cell;
}
-(void) refreshPressed: (id)sender
{
NSLog(#"Reload Pressed. Data size: %d", [articleArray count]);
[tblView reloadData];
}
Here is a screenshot of my .xib file with the connections:
So the main idea is the following:
Fetch articleArray
When refresh is pressed update view (the data is being fetched correctly but the snippet doesn't show it here)
numberOfRowsInSection and CellForRowAtIndexPath are only being called once when the view loads but nothing happens when I press the reload button.
I checked tblView and it is nil. I did some research and read that this is usually caused by some erroneous connections in the .xib file but I have triple checked that and I can't seem to pinpoint the problem.
Any help is appreciated,
Thanks!
You don't need to declare the UITableView tblView, the UITableViewController has already one (and therefore all subclasses too).
Just try [self.tableView reloadData];.

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!

Reusable TableView header views

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