Creating a custom UITableViewCell in iOS 4

This post explains how to create a custom table view cell that you can design  in Interface Builder and Xcode 4. Not only are the cells designable in IB, but they also have a code file in which you can place Outlets and Actions for controls in the cell, and encapsulate the cell’s logic in what’s basically a “code-behind” file (in .NET parlance).

The example also supports having the custom cells recycled by the UITableView, which can drastically improve memory consumption for long lists.

This shows how to create custom cells for iOS 4 apps. According to rumors coming out of WWDC 2011, Apple is making this easier for us when building iOS 5 apps.

Download the sample code and concise walkthrough here:

https://github.com/ijoshsmith/CustomCellDemo

The following instructions assume you already have a project with a UITableViewController in which you want to display custom cells.

Step 1: Add a new ViewController file with a XIB but change the base class from UIViewController to UITableViewCell. Delete the generated methods in the new .M file that do not apply to a UITableViewCell (viewDidLoad, viewDidUnload, etc). In the sample project, I named the files DemoTableViewCell, but the name is up to you.

Step 2: Open the new XIB file and make the File’s Owner the UITableViewController class that will be creating the custom cell. First select the “File’s Owner” item in the Placeholders section.

Then open the Utilities panel on the right side of Xcode 4, select the Identity Inspector icon, and then change the Class field to the name of the UITableViewController that will create/display this custom cell. In this example, I changed it to “DemoTableViewController”.

Step 3: Remove the File’s Owner’s link to the View outlet by clicking the ‘X’ button next to the word “View”.

Step 4: Select and delete the View in the XIB

Step 5: Locate Table View Cell in the Objects library and then drag one to the XIB’s design-time canvas.

Step 6: In the Identity Inspector pane, change the cell’s Class to your custom cell class name.

Step 7: Select the Cell on the design surface in IB, open the properties pane, and set the Identifier field to the name of your cell class. You should use the same identifier in the UITableViewController when trying to reuse instances of this cell via dequeueReusableCellWithIdentifier:.

Step 8: Assign Outlets and Actions to the Table View Cell object in IB, not File’s Owner like you normally would.

Step 9: Use UINib to create the XIB files for you when creating instances of table cells. UINib is more efficient than [[NSBundle mainBundle] loadNibNamed:…].  Refer to the code in DemoTableViewController in the sample project to see how to set this up.

This entry was posted in Interface Builder, UITableView, Xcode 4. Bookmark the permalink.

14 Responses to Creating a custom UITableViewCell in iOS 4

  1. Karl says:

    Is it time for a Seattle IOS Code Camp?

  2. GR says:

    I’m curious Josh, how you feel productivity compares to .NET/XAML? Because reading this post makes me think XAML is going to win when you want to do anything non-standard from a UX point of view.

    • Josh Smith says:

      GR,
      Some aspects of iOS programming are much less streamlined, while other things are easier than the .NET way. One thing about CocoaTouch that I like is that it forces you to use MVC and provides a great API for it. The coordination between Views and Controllers is largely taken care of for you, in terms of plumbing code.
      Josh

  3. Jean Fabre says:

    Thanks for this tutorial, Very useful! Providing a working example helps making sure that indeed it’s working, I have been trying other tutorials but since they don’t provide a working example, you don’t know if it’s you or the tut.

    Thanks again,

    Jean

  4. John says:

    Hi Josh,

    I started a new project and followed your steps above, however the “- (id)initWithStyle:(UITableViewStyle)style” message/method is not getting called (doesn’t get called at all) before the “- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath” call.

    What am I missing?

    I have download your demo project and it works, just don’t know what I’m doing wrong.

    Thanks,

    John

    • Josh Smith says:

      John,
      It could be a lot of things, but my shot in the dark is to verify your cell class derives from UITableViewCell and that you are instantiating your cell class from the table view controller.
      Josh

    • valenji says:

      I’ve the same problem as you, did you find the cause of this problem?

  5. Yagiz says:

    Alternatively, one can create an “Objective-C class” (instead of UIViewController subclass) and select “Subclass of UITableViewCell”.

  6. Jo Plaete says:

    Thanks for this! very helpful!

  7. Denis says:

    I love you!!! 😉

  8. Jiangwei says:

    Thanks for your tutorial!

    I have a question of Step 8: What’s the difference between pointing from ‘File’s Owner’ and from ‘Objects’? A proper tutorial on explaining these connection-related topics is also highly appreciated.

    Thanks!

Comments are closed.