从xib文件中加载UITableViewCell(这个类不符合键值编码关键字)

6
我很好奇如何正确地使用xib文件来布局UITableViewCell的内容。当我尝试按照在互联网上找到的所有步骤进行时,我总是会遇到以下错误:

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

这里是相关的代码:

@interface MyCell : UITableViewCell

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

在我的UIViewController中,我尝试了两种方法
-(void)viewDidLoad {
     [self.tableView registerNib:[UINib nibWithNibName:@"MyCell"
                                           bundle:[NSBundle mainBundle]]
     forCellReuseIdentifier:@"CustomCellReuseID"];
}

或者使用
- (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;
}

这两种方法都无法避免标题中提到的异常。 owner:self 的异常是因为 UIViewController 没有 IBOutlet 属性,而 owner:nil 的异常是因为它内部使用的是 NSObject,这个类也没有 IBOutlet 属性。
我找到的唯一变通方法如下。在我的单元格的 init 方法中,我将返回的视图/单元格添加到我的初始化单元格中。
例如:
- (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;
}

这似乎非常可疑(虽然我也可以将 xib 的基础类型更改为 UIView 而不是 MyCell 或 UITableViewCell),这使它感觉稍微不那么可疑。

我看到了许多人遇到了这个特定的错误。通常会将其解释为 xib 本身的连线问题,但如果我在 xib 中删除所有连接,它可以正常加载,但一旦我重新添加一个 ui 元素和文件所有者之间的连接,错误就会返回,所以我不认为这与“清理”xib有任何关系(即使查看 xib 的 XML,也没有列出任何错误的连接)。

还有其他人对此错误有什么想法吗?


你是否将Nib文件中的单元格的“自定义类”设置为“MyClass”? - Martin R
3个回答

4

我必须确保在创建输出时指定连接到单元格而非对象的所有者。当您从单元格中的标签拖动连接到类时,菜单会出现以便您命名它,并且您必须在“对象”下拉菜单中选择它(您可以选择“文件所有者”或单元格的类名称,选择单元格的类名称)。当然,您还必须将单元格的类声明为此类,而不仅仅是'TableViewCell'。否则我将继续收到“类不符合键”的错误。所以现在我有了那个类的单元格和文件所有者。


2
你是否在Cell Nib文件中连接了“messageLabel和statusLabel”的插座?错误指出Nib文件中未找到“statusLabel”的IBOutlet属性(连接问题)。

它已经与它的FileOwner正确连接。错误是说它在NSObject(或者如果我将MYViewController作为self传递给loadNibNamed:owner:中的所有者)上找不到statusLabel。 - Bryant Harris
1
从NIB加载视图并连接到FileOwner是行不通的,除非视图是UIViewController层次结构的一部分。您需要将NIB文件中UITableViewCell的outlet连接到标签。为此,请右键单击NIB中的UITableViewCell(您可以在左侧窗格下方找到它)并连接outlets。 - gagarwal
1
正确的连接方式是连接到您自定义的类,而不是FileOwner。当您将引用输出拖放到层次结构中的自定义类时,问题就解决了。问题在于IB允许您将其拖放到FileOwner上,并且存在您期望的IBOutlet,但它不起作用。将其拖放到自定义类上会显示相同的输出,但它可以正常工作。 - John

0

同时检查一下,确保 MyCell.xib 文件没有(错误地!)被添加进来

Target Settings -> Build Phases -> Compile Sources

编译源代码适用于所有.m文件,而不适用于.Xib资源文件。

复制捆绑资源适用于.Xib资源文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接