Use NIB-based UITableViewCell properly

I like to create my complex UITableViewCell objects in their own NIB files, as it helps me keep things well organized. Unfortunately, I felt like I was not able to use NIB-based UITableViewCell properly, as the implementation of this was always a bit clunky in my opinion, since I was relegated to doing something like this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *CellIdentifier = @"CellIdentifier";
 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
    {
        [[NSBundle mainBundle] loadNibNamed:@"MyCustomCell" owner:self options:NULL];
        cell = myCustomCell;
        self.myCustomCell = nil;
    }
 
    // do something here with the cell
 
    return cell;
}

Ugh, this was a bit messy. You had to make sure that your MyCustomCell.xib file had the file’s owner pointing back to your view controller class, and that you set up an IBOutlet to the cell.

The ability to take a project and require the latest version of iOS can be a refreshing thing, as it allows one to come up to the latest APIs and practices without having to maintain painful backward compatibility. Just such a thing happened today as I learned about the proper way to use a UITableViewCell from a NIB file.

This process involves registering a class or NIB file to work with a UITableView, hooked in through the cell identifier. To set up this registration, you would do something like this in your viewDidLoad method:

UINib *nib = [UINib nibWithNibName:@"MyCustomCell" bundle:nil];
[_theTableView registerNib:nib forCellReuseIdentifier:CellIdentifier];

(Just make sure to set up your CellIdentifier NSString variable as a global in the class or as a static in the same area that you register the NIB.) And then, the cellForRowAtIndexPath method has a little less heft to it:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
 
    // do something here with the cell
 
    return cell;
}

Because you have registered the NIB file with the cell identifier on your table view, the dequeueReusableCellWithIdentifier method knows how to either reuse or create a cell without having to explicitly do it in code. I like less heft.

BTW, Happy St. Patrick’s Day to everyone, Irish and non-Irish alike. Please be safe out there and don’t do anything dumb, which is actually a good rule to live by the other 364.24 days of the year as well.

Leave a Reply