4
votes

I was trying to create a custom UITableViewCell in Interface Builder and kept setting the File's Owner and Custom Class of the actual UITableViewCell to my new custom UITableViewCell Class. I would hook up the IBOutlets from the File's Owner and get errors when it came to:

 TVCell *cell = (TVCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {

    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"TVCell" owner:nil options:nil];

    for(id currentObject in topLevelObjects)
    {
        if([currentObject isKindOfClass:[TVCell class]])
        {
            cell = (TVCell *)currentObject;
            break;
        }
    }

Finally I realized you have to hook up the IBOutlets from the UITableViewCell Object, and not the File's Owner. Why is this?

Thanks

2

2 Answers

6
votes

The File's Owner is a placeholder object for the object that will eventually load the NIB. It's a way for objects outside the NIB to refer to objects inside the NIB. In your case, you're trying to create the table view cell from the NIB, so you'll need some other object to be the owner. The table view cell can't both be outside and inside the NIB.

In this line of your code:

NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"TVCell" 
                                                         owner:nil
                                                       options:nil];

You get to specify an object for the File's Owner placeholder in Interface Builder to resolve to. I'm guessing your code is in a class like 'MyTableViewController'. If it is, you could pass 'self' for the owner parameter to -[NSBundle loadNibNamed:owner:]. If you did that, you could have outlets on the MyTableViewController class that would be useful for loading this NIB. Specifically, you could use them to avoid the for loop you have. You'd do that like this:

  • Add a 'loadedTableViewCell' outlet to MyTableViewController
  • In the table cell nib, set the file's owner to MyTableViewController.
  • Make a connection for 'loadedTableViewCell' from the file's owner to the table view cell.

Then change your code to be similar to this:

TVCell *cell = (TVCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    [[NSBundle mainBundle] loadNibNamed:@"TVCell" owner:self options:nil];
    cell = [self loadedTableViewCell];
    [self setLoadedTableViewCell:nil];
}
0
votes

It's because you're pulling objects out of the nib, not using the whole nib, like you would if you were loading a controller. That's what the for (id currentObject in topLevelObjects) does.