Ohhk, quite a lot of things done but this one is something which I have used most often. Custom cells can sometimes greatly push ahead the usability of your application. In this post I am going to create a test project which will demonstrate how to create custom cells and use them appropriately to provide better usability. The application will finally look like this:
#import
@interface CustomCell : UITableViewCell {
UILabel *primaryLabel;
UILabel *secondaryLabel;
UIImageView *myImageView;
}
@property(nonatomic,retain)UILabel *primaryLabel;
@property(nonatomic,retain)UILabel *secondaryLabel;
@property(nonatomic,retain)UIImageView *myImageView;
@end
- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) {
// Initialization code
primaryLabel = [[UILabel alloc]init];
primaryLabel.textAlignment = UITextAlignmentLeft;
primaryLabel.font = [UIFont systemFontOfSize:14];
secondaryLabel = [[UILabel alloc]init];
secondaryLabel.textAlignment = UITextAlignmentLeft;
secondaryLabel.font = [UIFont systemFontOfSize:8];
myImageView = [[UIImageView alloc]init];
[self.contentView addSubview:primaryLabel];
[self.contentView addSubview:secondaryLabel];
[self.contentView addSubview:myImageView];
}
return self;
}
@synthesize primaryLabel,secondaryLabel,myImageView;
- (void)layoutSubviews {
[super layoutSubviews];
CGRect contentRect = self.contentView.bounds;
CGFloat boundsX = contentRect.origin.x;
CGRect frame;
frame= CGRectMake(boundsX+10 ,0, 50, 50);
myImageView.frame = frame;
frame= CGRectMake(boundsX+70 ,5, 200, 25);
primaryLabel.frame = frame;
frame= CGRectMake(boundsX+70 ,30, 100, 15);
secondaryLabel.frame = frame;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#import “CustomCell.h”
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @”Cell”;
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell…
switch (indexPath.row) {
case 0:
cell.primaryLabel.text = @”Meeting on iPhone Development”;
cell.secondaryLabel.text = @”Sat 10:30″;
cell.myImageView.image = [UIImage imageNamed:@"meeting_color.png"];
break;
case 1:
cell.primaryLabel.text = @”Call With Client”;
cell.secondaryLabel.text = @”Planned”;
cell.myImageView.image = [UIImage imageNamed:@"call_color.png"];
break;
case 2:
cell.primaryLabel.text = @”Appointment with Joey”;
cell.secondaryLabel.text = @”2 Hours”;
cell.myImageView.image = [UIImage imageNamed:@"calendar_color.png"];
break;
case 3:
cell.primaryLabel.text = @”Call With Client”;
cell.secondaryLabel.text = @”Planned”;
cell.myImageView.image = [UIImage imageNamed:@"call_color.png"];
break;
case 4:
cell.primaryLabel.text = @”Appointment with Joey”;
cell.secondaryLabel.text = @”2 Hours”;
cell.myImageView.image = [UIImage imageNamed:@"calendar_color.png"];
break;
default:
break;
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50;
}


[...] Customizing cells in the table [...]
awesome post ..
it helps me alot..
program works fine but it gives a warning
initialization from distinct objective-c type
I have always tolerated some harmless warnings
but can u tell me where exactly u found this warning, m kinda away from my work station
I got the “initialization from distinct objective-c type” warning as well, what was causing it?
OK, figured it out. I had to cast the new cell because the id don’t match…
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Found the reference to is here: http://blog.andrewpaulsimmons.com/2008/07/warning-initialization-from-distinct.html
This approach works excellent but if you choose for a grouped UITableView, does that change things in terms of positioning of the labels and imageViews? I have the impression that I can’t position all subviews as precisely as I can in, for example, interface builder.
Any comments?
Hello bare_nature,
No I don think not using grouped UITableView would affect the positioning of any sybViews.
Regarding IB and this approach, precision wise it shouldn make difference but yest with IB you can do d same thing faster.
I m used to writing graphics like this bt the main reason behind this approach is that it gives me a lot of control and I can re-use the same code over and over again with little modifications. If we used xib(s) then re-using or re-customization ultimately takes more time.
Correct me if I am wrong, I am looking for some serius motivation 2 use IB
Its Really Great Dude
For a new bee like me it works out great. I was working out with the same kind of app and fortunately i got in to ur blog and done with the work.
Now i would like to display the zoomed image in the detailed view when i tap on the disclosure indicator.
if possible please post the code for me naa.
Simple, very clear and very helpful. Thanks for the post
Hi Ram, sorry for the late reply. I can not write d code here coz m currently bzzy with other obligations but I can give suggestions.
As such I don understand what u wnat to do, but if you jus want to zoom on image den u can create a UIImageView of larger frame and put the same image in.
I have alreay built an app with a tableview, but would love to use this as the opener for the app. My rootviewcontroller already has all the code for the existing tableview. Is there a way to do this?
Thanks in advance,
D
OK, I’ve done this tutorial 7 times now and all I get is a black screen. What gives?
Figured out my issue with the blank screen. Still wondering if I can incorporate it into my existing project and another big QUESTION: How would I have the fields filled from a .plist?
Is there a download link for the complete Xcode project somewhere? I can’t seem to find it on the page. Great topic by the way.
Thanks!
Hi,
How do I change the default height of the table cell? I tried increasing the heights of myImageView.frame and primaryLabel.frame but the text got clipped.
where is the code and images for this article please.
thanks for good starting point
Great example. Thanks!
Hi liveCity,
Just create a custom cell like that say MyCustomCell and replace it with UITableViewCell in the rootViewController…let me know if there are any issues..and btw sorry for the late reply.
Hi,
First: sorry for the late reply.
Second: I will put all my working code on rapidshare and provide a link soon. Just need a day or two.
Hi, i did it all like you say but when i try in iphone simularot it cannot run,always a suddenly error,with another of your appilcations it happens too.but i good tutorial but i want to run it
Do you have source code for this?
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
error: ‘CustomCell’ undeclared (first use in this function)
error: ‘cell’ undeclared (first use in this function)
Any clue why I’d be getting these errors?
Thanks.
You are getting this error prolly coz u did not make any CustomCell.m and CustomCell.h?
Hi ABC,
Nope, I have created the full CustomCell.m and .h files.
Hi,
My table cells have fixed height until selected. On selection I want to increase the hight of the selected cell. I have tried something but the selected cell is overlapping the next cell.
Please let me know how will i resize the table so that there are no overlapping cells
Thanks
Sam
First of all great tutorial. It helped me to clarify some questions. However, when I try to adapt the cell class to use a UITextField for some cells in addition to the existing UILabel on other cells, things get a little nasty. Mainly the problem has to do with: CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; If the cell is getting reused, because of a scrolling on the table view, a cell with a label control might be reused by dequeueReusableCellWithIdentifier when in fact the indexPath.row is for a row which needs a UITextField. I have a workaround now, but I believe it leads to memory leak issues. Any ideas ??
What about orientation changes? Doesn’t handle them well, does it?
GFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50;
}
when i use this i got an error saying “pointer value used where a floating value expected..any suggestions?
thanks
My cell is blank…Why???…
Im getting a warning – > warning: incompatible Objective-C types initializing ’struct UITableViewCell *’, expected ’struct CustomCell *’
And that is regarding the following code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @”Cell”;
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
Any advice would make a sad man happy again. Thank you!
To fix the warning, replace
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
with
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
That will fix the problem,
Ad
Steve,
an explicit cast for *cell is required, just put a (CustomCell *) before the assignment:
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Should work now without any warnings.
Steve
Try this
CustomCell *cell =(CustomCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Hi Great tutorial with nice explanations.I have a query here, Can i have a customized screen with labels,table view and other desired control but with a precondition that i get a navigation Controller through out the application? My requirement is to be easily able to toggle between view.If I choose a view based application as template then i guess i will have to maintain my own stack for multiple view,which is provided by default by navigation controller.Can u suggest me something. ***I liked your approach to design all controls melodramatically***. I will be waiting for your reply . thanks and Cheers
Great !!!!!!!
Really it helped me a lot. Thank you very much……
Hi,
I want to put a UITextField into a UITableViewCell. I did, but now a can’t edit the content of the UITextField. Is possible put the UITextField and edit the content of this by user?
Hi, Thank you for great post !
It works fine but I’ve got a warning as followings..
‘initWithFrame:reuseIdentifier:’ is deprecated (declared at /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.2.sdk/System/Library/Frameworks/UIKit.framework/Headers/UITableViewCell.h:188)
at
if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) {
I’m using in Split View-Based Application.
Could you please give some advice ?