Loading UITableViewCell from a xib (this class is not key value coding-compliant for the key)

4k views Asked by At

I'm curious as to the proper way to use a xib file to layout the contents of a UITableViewCell. When I try to follow all the steps I find on the Internet I always get

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSObject 0x10fe7d790> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key statusLabel.'

So here's the related code

@interface MyCell : UITableViewCell

@property (nonatomic,strong) IBOutlet UILabel* messageLabel;
@property (nonatomic,strong) IBOutlet UILabel* statusLabel;

And in my UIViewController I've tried both

-(void)viewDidLoad {
     [self.tableView registerNib:[UINib nibWithNibName:@"MyCell"
                                           bundle:[NSBundle mainBundle]]
     forCellReuseIdentifier:@"CustomCellReuseID"];
}

or using

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"CustomCellReuseID";
    MyCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if ( !cell ) {
        cell = [[[NSBundle mainBundle] loadNibNamed:@"MyCell" owner:self options:nil] 
lastObject];
        // or sometimes owner is nil e.g.
        //cell = [[[NSBundle mainBundle] loadNibNamed:@"MyCell" owner:nil options:nil] 
lastObject];
    }

    // ... remainder of cell setup

    return cell;
}

Both of these approaches fail with the exception I mentioned in the title. It appears that with owner:self the error is because the UIViewController doesn't have the IBOutlet properties. With owner:nil it's because it internally uses an NSObject which of course also doesn't have the IBOutlet properties.

The only work around I've found is as follows. Within the init method for my cell I add the returned view/cell to my initializing cell

e.g.

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // nil out properties

        [self.contentView addSubview:[[[NSBundle mainBundle] loadNibNamed:@"MyCell" owner:self options:nil] lastObject]];
    }
    return self;
}

This seems really hokey (although I can also just change the base type in the xib to UIView instead of MyCell or UITableViewCell) which makes it feel slightly less hokey.

I've seen a lot of posts where people run into this particular error. This is usually explained away as being a wiring problem in the xib itself, however if I remove all connections in the xib it loads fine, but the moment I add back a connection between a ui element and the file owner the error returns, so I don't think it has anything to do with 'cleaning up' the xib (even looking at the XML for the xib there's no errant connections listed).

Does anyone else have any thoughts as to how this error comes about?

3

There are 3 answers

3
gagarwal On

Have you connected the outlets for "messageLabel and statusLabel" in the Cell Nib file? The error states that the IBOutlet property for "statusLabel" is not found in the Nib file (connection issue).

0
buckleyJohnson On

I had to make sure that when creating the outlet to specify that I was hooking to the cell, not the object's owner. When you drag your connection from the label in your cell to the class, the menu appears so you can name it and you have to select it in the 'object' dropdown menu (you can choose 'files owner' or the cell's class name, choose the cell's class name). Of course you must declare the cell's class as this class too, not just 'TableViewCell'. Otherwise I would keep getting the class not key compliant. So now I have both the cell and the files owner named of that class.

0
Vinod Supnekar On

Also Check If MyCell.xib file is not (mistakenly!) get added inside

Target Settings -> Build Phases -> Compile Sources

Compile Sources are For All .m Files and Not for .Xib resource files.

And

Copy Bundle Resources are for .Xib resource files.