Custom UITableViewCell

Make sure you have JSON Framework installed first.

This is a continuation of More Complex JSON endpoint

The reason why OOP is so powerful is that you can subclass everything to make it work or look just how you want it. The default look of a UITableViewCell is just one line of text. If you want to add some text below it you need to subclass that. So that is what we will do right now.

The first thing we want to do is create a new subclass in your project. You should know how to do this already. File -> New File and select a UITableViewCell subclass. I have named mine ImageCell

Now you can see we have the title in nice big letters and the URL to the image under in in smaller letters and also in grey

I am just going to paste all the code and I have made some comments to show you what I added

First your ImageCell.h should look like


@interface ImageCell : UITableViewCell {
	// adding the 2 labels we want to show in the cell
	UILabel *titleLabel;
	UILabel *urlLabel;

// these are the functions we will create in the .m file

// gets the data from another class
-(void)setData:(NSDictionary *)dict;

// internal function to ease setting up label text
-(UILabel *)newLabelWithPrimaryColor:(UIColor *)primaryColor selectedColor:(UIColor *)selectedColor fontSize:(CGFloat)fontSize bold:(BOOL)bold;

// you should know what this is for by know
@property (nonatomic, retain) UILabel *titleLabel;
@property (nonatomic, retain) UILabel *urlLabel;


There really isn’t any magic going on in the header. So now open up the ImageCell.m file and my contents are as follows.

#import "ImageCell.h"

@implementation ImageCell

// we need to synthesize the two labels
@synthesize titleLabel, urlLabel;

- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier {
	if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) {
		// Initialization code

		// we need a view to place our labels on.
		UIView *myContentView = self.contentView;

		 init the title label.
		 set the text alignment to align on the left
		 add the label to the subview
		 release the memory
		self.titleLabel = [self newLabelWithPrimaryColor:[UIColor blackColor] selectedColor:[UIColor whiteColor] fontSize:14.0 bold:YES];
		self.titleLabel.textAlignment = UITextAlignmentLeft; // default
		[myContentView addSubview:self.titleLabel];
		[self.titleLabel release];

		 init the url label. (you will see a difference in the font color and size here!
		 set the text alignment to align on the left
		 add the label to the subview
		 release the memory
        self.urlLabel = [self newLabelWithPrimaryColor:[UIColor blackColor] selectedColor:[UIColor lightGrayColor] fontSize:10.0 bold:NO];
		self.urlLabel.textAlignment = UITextAlignmentLeft; // default
		[myContentView addSubview:self.urlLabel];
		[self.urlLabel release];

	return self;

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {

	[super setSelected:selected animated:animated];

	// Configure the view for the selected state

 this function gets in data from another area in the code
 you can see it takes a NSDictionary object
 it then will set the label text
-(void)setData:(NSDictionary *)dict {
	self.titleLabel.text = [dict objectForKey:@"title"];
	self.urlLabel.text = [dict objectForKey:@"img"];

 this function will layout the subviews for the cell
 if the cell is not in editing mode we want to position them
- (void)layoutSubviews {

    [super layoutSubviews];

	// getting the cell size
    CGRect contentRect = self.contentView.bounds;

	// In this example we will never be editing, but this illustrates the appropriate pattern
    if (!self.editing) {

		// get the X pixel spot
        CGFloat boundsX = contentRect.origin.x;
		CGRect frame;

		 Place the title label.
		 place the label whatever the current X is plus 10 pixels from the left
		 place the label 4 pixels from the top
		 make the label 200 pixels wide
		 make the label 20 pixels high
		frame = CGRectMake(boundsX + 10, 4, 200, 20);
		self.titleLabel.frame = frame;

		// place the url label
		frame = CGRectMake(boundsX + 10, 28, 200, 14);
		self.urlLabel.frame = frame;

 this function was taken from an XML example
 provided by Apple

 I can take no credit in this
- (UILabel *)newLabelWithPrimaryColor:(UIColor *)primaryColor selectedColor:(UIColor *)selectedColor fontSize:(CGFloat)fontSize bold:(BOOL)bold
	 Create and configure a label.

    UIFont *font;
    if (bold) {
        font = [UIFont boldSystemFontOfSize:fontSize];
    } else {
        font = [UIFont systemFontOfSize:fontSize];

	 Views are drawn most efficiently when they are opaque and do not have a clear background, so set these defaults.  To show selection properly, however, the views need to be transparent (so that the selection color shows through).  This is handled in setSelected:animated:.
	UILabel *newLabel = [[UILabel alloc] initWithFrame:CGRectZero];
	newLabel.backgroundColor = [UIColor whiteColor];
	newLabel.opaque = YES;
	newLabel.textColor = primaryColor;
	newLabel.highlightedTextColor = selectedColor;
	newLabel.font = font;

	return newLabel;

- (void)dealloc {
	// make sure you free the memory
	[titleLabel dealloc];
	[urlLabel dealloc];
	[super dealloc];


So now we can save that file and open up RootViewController.m

We need to add in a import

#import "ImageCell.h"

Now go down to the cellForRowAtIndexPath function. Right now we have a UITableViewCell *cell call to init the cell, we need to change that since we are using our new ImageCell class. So replace that line with

ImageCell *cell = (ImageCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];

Also we need to replace the cell = line in the if (cell == nil) if statement

cell = [[[ImageCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];

Now remove the cell.text line and replace it with the following

NSDictionary *itemAtIndex = (NSDictionary *)[self.jsonArray objectAtIndex:indexPath.row];
[cell setData:itemAtIndex];

Now you can build and go and you should get the following

As you can see you now have the title in nice big letters and the URL in smaller gray letters below the title. As always you can grabt he source code here.

About mike
Currently works for Recurly as a Senior Linux Admin. He has a wonderful wife Thanuja and 2 great children (Anusha and Brandon). His major side project is Photoblog.

  • Brian

    I’ve been researching how to do this all day! Thanks! BTW, the source code link is broken.

  • mikezupan

    It took me a bit to really figure it out.. I had it hours before I thought I did but I messed up on the cellForRowAtIndexPath function.. I changed the cell init for the first but not if it was nil and my app keep crashing.

    Thanks for pointing out about the source.. the link is fixed now

  • John

    wanted to say thanks.. with the NDA information like this is hard to come by.. esp. the more advanced things like web services and subclassing. Thanks again.


  • mikezupan


    no problem. I could care less about the NDA.

    I personally think it is there cause Apple changed a lot from the first beta of the SDK to the one there now. I think they didn’t want a lot of bad tutorials out there to discourage people.

    that is just purely a guess though

  • xavier

    Very very usefull entry .. very usefull blog .. I’m definitly learning with you :)

    thanks keep up the good work

  • zeddy

    Very good tutorial :)

    Is there any way of making the cells resize according to the amount of text in the labels?

    I’ve set the labels to have multiple lines, but the part where you set the frame causes problems for dynamic content.

  • Pingback: App like weather - iPhone Dev SDK Forum()

  • Mark

    Was just about to program an application that needed this (I’m a noob) that integrates with my price check site ( You example code should work a treat to get me going.

    Thanks mate.

  • Jeremy

    Great posts, have really helped.

    I am trying to extend this example to add an image to each row however so far I seem to be able to make the frame but no picture appears?

    Any Ideas?

  • mikezupan


    I was able to add photos just fine to a custom cell. Make sure you do the following

    1) init the image in a UIImage
    2) load the image in a UIImageView
    3) add the UIImageView to the subview which i call it MyContentView
    4) in the layoutSubviews make sure you draw it.

    Sometimes I have forgotten to add the subview and it doesn’t show up..

    If you are still suck post your code somewhere and I can take a look

  • Jeremy

    Hmm maybe my dictionary object is incorrect.

    [menuArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:
    NSLocalizedString(@”Test Title”,@””), @”title”,
    NSLocalizedString(@”Test”,@””), @”description”,
    [UIImage imageNamed:@”test.png”],@”testimg”,

    2) self.testImageView = [[UIImageView alloc] initWithImage:[dict objectForKey:@”testimg”]];

    3) [myContentView addSubview:self.testImageView];

    4) frame = CGRectMake(boundsX +5, 4, 40, 40);
    self.testImageView.frame = frame;

    Anything obvious?

  • mikezupan

    Here is how I am doing it.. Now my images are pulled from a webservice so I load them via JSON

    noPicImageSmall = [[UIImage imageNamed:@”nopic-small.png”] retain];

    UIImageView *img1 = [[UIImageView alloc] initWithImage:noPicImageSmall];
    img1.hidden = YES;
    [MyContentView addSubview:img1];
    [imgArray addObject:img1];
    [img1 release];

    might be some issue with how you are loading the image.. also make sure you added it to your Xcode project

  • Nicolas

    Hi Mike,

    Thanks for the great tutorials!

    One question, do you plan writing a tutorial on creating a view from a json resource?

    I have the table with all my items, but I have no idea how to make the links clickable and go to a detailed view of that particular item.

  • Turbolag

    Great tutorial, I’ve been trying to do this for a while.

    However, I would like to edit the size of each cell, so I could fit a 40×40 image in. I have replaced the CGRectZero in newLabelWithPrimaryColor with CGRectMake(8.0, 10.0, 260.0, 80.0), but I dont see any change. How do I increase the size of each cell?

  • mikezupan


    the only way I have found to edit the height of a cell is doing it in the tableView.

    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 100.0; //returns floating point which will be used for a cell row height at specified row index

  • mikezupan

    There is a post on how to create a new view from a cell click

  • Turbolag

    Thanks, worked great!

    I have added an image to each cell with the following code in setData:

    UIView *myContentView = self.contentView;
    self.image = [UIImage imageNamed: [dict objectForKey:@”image”]];
    UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
    [myContentView addSubview:imgView];

    But this doesn’t follow the method used above where the view is loaded in initWithFrame. When I add the view in initWithFrame, and set the image in setData, the image is not displayed. What code should be placed in initWithFrame?

  • mikezupan

    your self.image line assumes that whatever is in the dictionary for image is already a image resource loaded into a UIImage.

    Here is how I do it for my main app. I have a nopic image that I load by default to show a waiting icon or such then when the real image is loaded it will replace it.

    noPicImageSmall = [[UIImage imageNamed:@”nopic-small.png”] retain];

    So nopic-small.png is in my project

    UIImageView *img1 = [[UIImageView alloc] initWithImage:noPicImageSmall];
    [MyContentView addSubview:img1];
    [img1 release];

    Also make sure you are drawing your image in the layoutSubviews method

  • Turbolag

    So correct me if I’m wrong,

    initWithFrame should contain:
    noPicImageSmall = [[UIImage imageNamed:@”nopic-small.png”] retain];
    UIImageView *img1 = [[UIImageView alloc] initWithImage:noPicImageSmall];
    [MyContentView addSubview:img1];
    [img1 release];

    And setData should contain to update the image for each cell:
    self.image = [UIImage imageNamed: [dict objectForKey:@”image”]];

    What exactly do you mean by drawing image in layoutSubviews meathod? Do you have any source code you can provide?

  • mikezupan

    The next tutorial will be about placing a image in a custom cell

  • mikezupan


    Here is a link to adding a UIImageView to a custom cell

  • john

    Hi, the sample doesn’t compile (at least for me (it says it needs iphone simulator.sdk) I can compile tons of other sample apps…

  • mikezupan


    thanks the sample code is fixed

  • http://n/a Halbert

    Awesome post!

    Do you know if its possible to do what you did in code via the Interface Builder?

    Since the code is just subclassing a TableViewCell and adding and positioning subviews to it, it would be easier if you could just do this using an editor, ie the Interface Builder.

    Right now, I’m using the Interface Buildter to visually layout my table cell. When I have it the way I like it, I record all the positions and sizes of each subview element and then write it in code. Very tedious.

  • Pingback: UITableViews Tutorial Part #1 - iPhone Dev SDK Forum()

  • Pingback: Custom UICellView Tutorial - iPhone Dev SDK Forum()

  • mikezupan


    I don’t think you can do that. If you want to do it in IB you can create a new uiview and create a subclass for that and in the cell set the view to load up that xib file probably

  • samken

    Thanks. You are a champ.

  • billgajen

    Hi I am a beginner,

    I don’t understand where I have to replace

    NSDictionary *itemAtIndex = (NSDictionary *)[self.jsonArray objectAtIndex:indexPath.row];
    [cell setData:itemAtIndex];

    I can’t find cell.text line anywhere

    Can you help me. And the sample code is not workoing


  • mikezupan

    there is no cell.text since I am setting the text in the custom cell class

  • Pingback: Cell Customization - iPhone Dev SDK Forum()

  • Pingback: Cell Customization - iPhone Dev SDK Forum()

  • Pingback: JSON Error : Iphone Noob()

  • Davide

    Thanks mate, this tut is exactly what I was looking for. The framework is well documented, but somehow it is hard to find the information.

  • Pingback: I Hate UITableViews - iPhone Dev SDK Forum()

  • Pingback: links for 2009-01-04 at

  • Gary

    This just saved me about 4 hours of banging my head against the wall. Thanks!

  • Luis

    Ironically, I cannot view your code blocks on my iPhone. They’re cut off on the right. Boo.

  • BHSPitMonkey

    Luis: Use a two-finger swipe to scroll around in the code blocks.

  • rahulvyas

    please tell me how to add multiple buttons programmatically in Custom Cells in diferent row and show new view from that button…?

  • Pingback: Custom UITableViewCell : Iphone Noob « RadiantPhone Devlog()

  • dineshkumarm12

    I want to have a two cell in a row,as in contacts we have “Text message” and “Add to favourites” in a single row how to do that….
    Is that Splitting a cell into two?

    can anyone help me?

  • MeggoSexxx


  • podarki

    Вообще, на мой взгляд, самое лучшее в личном блоге, так это самопознание.

  • Pingback: Rolling your own iPhone treeview control Part 3: Creating a treeview-ready UITableViewCell « .NET @ Kape ni LaTtEX()

  • Raed

    When I trying to run the source code I got this error !!

    Command /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc-4.2 failed with exit code 1

  • mum


  • mum

    since u are taking label text from xml,if i have multiple section for each setion i need different label text like…

    section 1


    section 2

    how can i declare differnt uitableviewcell for differntlabel

  • Eric Goldberg

    Just as a heads-up, your UILabel constructor method will leak memory as implemented. You should return an autoreleased UILabel. Or, on the caller side, set the instance property in a way that doesn’t add a retain. However, doing the autorelease way is cleaner and more the “Apple Way” since you’re supposed to balance any init / copy calls with a release / autorelease in the same method.


  • Herbert Altink

    Good tutorial!

    Here is another interesting tutorial!