0

I am trying to create a custom table view cell with a xib but when I call:

CustomReferenceTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

I get the following:

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

Here is my setup:

- (void)viewWillAppear:(BOOL)animated   
{
    [self.tableView registerNib:[UINib nibWithNibName:@"CustomReferenceTableViewCell"
                                           bundle:[NSBundle mainBundle]]
     forCellReuseIdentifier:@"referenceCell"];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"referenceCell";

     CustomReferenceTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
         cell = [[CustomReferenceTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }

    cell.number.text = @"1";
    cell.referenceName.text = @"Name";
    cell.reference.text = @"The text of the reference";

    return cell;
 }

Here is a picture of my connections in interface builder. Also my cellIdentifiers match between class and xib:

enter image description here

I have seen this post here but I still can't seem to get it work.

Help would be greatly appreciated.

Edit

Here is a pic showing setting of custom class. Below that is my initialiser for the tableViewCell:

enter image description here

Here is the header:

#import <UIKit/UIKit.h>

@interface CustomReferenceTableViewCell : UITableViewCell

@property (nonatomic, weak) IBOutlet UILabel *number;
@property (nonatomic, weak) IBOutlet UILabel *referenceName;
@property (nonatomic, weak) IBOutlet UILabel *reference;

@end

And here is the implementation:

#import "CustomReferenceTableViewCell.h"

@implementation CustomReferenceTableViewCell

- (void)awakeFromNib {
    // Initialization code
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

@end
Community
  • 1
  • 1
pls
  • 1,522
  • 2
  • 21
  • 41
  • Please can you post your code for CustomReferenceTableViewCell initialiser – pbasdf Oct 28 '14 at 11:10
  • I assume `reference`, `referenceName` and `number` are all declared as properties in CustomRefernceTableViewCell.h – pbasdf Oct 28 '14 at 11:19
  • Yes there are. They are all IBOutlets hooked up in the xib. – pls Oct 28 '14 at 11:23
  • Check the Connections inspector for each of those labels in IB: does any of them have a connection to a different property name? – pbasdf Oct 28 '14 at 11:28
  • @pls it's useful for you http://www.appcoda.com/customize-table-view-cells-for-uitableview/ – Pavan Alapati Oct 28 '14 at 11:30
  • I removed all connections and it didn't crash. However when I re added one back it crash again. – pls Oct 28 '14 at 11:32
  • In your images of the XIB, it looks like you are showing the details for "Files Owner". Is the `UITableViewCell` itself configured with the right class and connections? – pbasdf Oct 28 '14 at 11:42
  • Both file owner and the cell are set to the same class. I can only connect outlets from the files owner. – pls Oct 28 '14 at 12:07

4 Answers4

3

I think you are setting the file owner of the cell to your custom cell which you shouldn't do. The way to get things working for a custom cell is,

  1. In your xib, have a Table View Cell component an populate the contents of the cell in its ContentView.

  2. Make your class CustomReferenceTableViewCell as the Custom Class of that cell component.

  3. Now, do NOT register the cell in your tableview; instead do the following in the cellForRowAtIndexPath when your cell is nil after [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; and then register it:

    cell = [self.tableView dequeueReusableCellWithIdentifier:cellID];
    if(cell == nil) {
        [self.tableView registerNib:[UINib nibWithNibName:[@"CustomReferenceTableViewCell" ] bundle:nil] forCellReuseIdentifier:cellID];
        NSArray *nibContents;
        CustomReferenceTableViewCell *cell;
        nibContents = [[NSBundle mainBundle]
                       loadNibNamed:nibName owner:self options:NULL];
        NSEnumerator *nibEnumerator = [nibContents objectEnumerator];
        NSObject *nibItem = nil;
        while ((nibItem = [nibEnumerator nextObject]) != nil) {
            if ([nibItem isKindOfClass:[CustomReferenceTableViewCell class]]) {
                cell = (CustomReferenceTableViewCell *)nibItem;
            }
        }
    }
    

This method has been working out for me for the past 8 months. I have no reasons why it could cause a problem to you.

avismara
  • 5,141
  • 2
  • 32
  • 56
  • If I don't set the files owner to the custom view I can't hook up my IBOutlets. – pls Oct 28 '14 at 12:05
  • "Make your class CustomReferenceTableViewCell as the Custom Class of that cell component." – avismara Oct 28 '14 at 12:53
  • Have given you a +1 for pointing out I shouldn't be setting files owner. – pls Oct 28 '14 at 14:04
  • This solution works. However after finding what was causing the crash (see comment above), my code worked fine. So it can be used if you don't require the extra code of checking the class type as in codingVoldermort's answer. Also see my answer below if you have issues with connecting IBOutlets to custom tableview cells. – pls Oct 28 '14 at 22:52
  • Good tip.! not registering cell saved my day..! :D – Yash Bedi Feb 16 '20 at 18:07
  • Whoa, this post is helpful even after 6 years? Something to think about. :D – avismara Feb 16 '20 at 19:24
2

Try to set your static NSString *cellIdentifier = @"referenceCell"; above @interface And change registerNib place from WillAppear to viewDidLoad. Also you can change cell creating

CustomReferenceTableViewCell *cell = (CustomReferenceTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
     cell = [[[NSBundle mainBundle]loadNibNamed:@"CustomReferenceTableViewCell" owner:self options:nil] lastObject];
}
NilsHolgerson
  • 264
  • 2
  • 11
0

Just follow my coding for your app

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {

    CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:@"Reuse"];

    NSArray *nib=[[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];

    if(cell == nil)
    {
       cell = [nib objectAtIndex:0];
    }

    cell.number.text = @"1";

    cell.referenceName.text = @"Name";

    cell.reference.text = @"The text of the reference";

    return cell;

  }
user3182143
  • 9,459
  • 3
  • 32
  • 39
0

Firstly CodingVoldermort's answer helped me get to sort out the issue. I was setting the File's Owner to my custom class which you shouldn't do. This should be left as NSObject.

The reason I thought it needed to be changed was because I couldn't hook up my IBOutlets by holding control and clicking on the tableview image under placeholders and dragging to the appropriate view in the xib.

Instead I needed to go under 'Show the connection inspector' pane and control + click and drag from there to get the connections to work. Then my original posted code would work.

Many thanks for all the responses guys.

pls
  • 1,522
  • 2
  • 21
  • 41