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:
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.
Is it time for a Seattle IOS Code Camp?
I would love to attend one!
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.
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.
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.
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.
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.
I’ve the same problem as you, did you find the cause of this problem?
Alternatively, one can create an “Objective-C class” (instead of UIViewController subclass) and select “Subclass of UITableViewCell”.
Yes you can do.. Here is a tutorial how to do that. http://www.altinkonline.nl/tutorials/xcode/uitableview/uitableviewcell/
Thanks for this! very helpful!
I love you!!! 😉
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.