iOS - dequeueReusableCellWithIdentifier 返回带有 nil 字段的 Cell

Posted

技术标签:

【中文标题】iOS - dequeueReusableCellWithIdentifier 返回带有 nil 字段的 Cell【英文标题】:iOS - dequeueReusableCellWithIdentifier return Cell with nil fields 【发布时间】:2016-12-21 23:52:48 【问题描述】:

我有两个UITableView,我想为这两个UITableView 使用相同的自定义单元格。 问题是其中只有一个可以正常工作。只有第一个表显示行。

当我调试时,我看到第二个表的 cell.lb_subject 为零。

MyCustomCell 仅在第一个表上被定义为 原型单元格(不是 xib),因为我没有看到定义同一行两次的意义。

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


        static NSString *simpleTableIdentifier = @"MyCustomCell";

        MyCustomCell *cell = [mytableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

        if (cell == nil) 
            cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
        
        MyRowData* data = [tableData objectAtIndex:indexPath.row];
        cell.lb_subject.text = data.subject;
我有两个 UIViewController 每个 UIViewController 一个表 我没有 Xib,我有故事板。 我已将 demo 上传到我的 repo

【问题讨论】:

我不清楚您所说的“MyCustomCell 仅在第一个表上被定义为原型单元格,因为我没有看到定义同一行两次的意义。”你的意思是“我只为 Interface Builder 中的第一个表设置了原型单元格的类”,还是“我只为第一个表调用了 registerClass:forCellReuseIdentifier:”,还是别的什么? @Palpatim 第一个。 尝试在界面生成器的第二个表格中定义原型单元的类。您实际上并没有定义同一行,而是在告诉系统“使用此类作为此场景中表格的原型行的实现。” 但我必须设计两次相同的单元格,并连接iboutlets,对吧? 抱歉,我将情节提要中的原型单元格与 nib/xib 单元格混为一谈。我常用的方法是定义一个 nib/xib 并将其用作单点控制,如***.com/questions/26342151/… 中所述 【参考方案1】:

按照此步骤操作。

你的 ViewController

ViewController.h

NSMutableArray *tableData;

ViewController.m

- (void)viewDidLoad

    [super viewDidLoad];
    tableData = [[NSMutableArray alloc]initWithObjects:@"test1",@"test2",@"test3",nil];


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    return [tableData count];


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

    //Here MyCustomCell is identifier for both tableview cell.
    static NSString *simpleTableIdentifier = @"MyCustomCell";

    //tblCell is your custom tableview cell.
    tblCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

    if (cell == nil) 
        cell = [[tblCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
    
    cell.lb_subject.text = [tableData objectAtIndex:indexPath.row];
    return cell;

您的自定义单元格

tblCell.h

//Here lb_subject is common Outlet for both label of both cell.
@property (strong, nonatomic) IBOutlet UILabel *lb_subject;

【讨论】:

我已经向我的仓库上传了一个演示 github.com/rchampa/ios-ReusePrototypeCell【参考方案2】:

为您的两个表提供标签,然后分别对两个表使用 dequeueReusableCellWithIdentifier。

 if (tableView.tag==1) 

    static NSString *simpleTableIdentifier = @"MyCustomCell";

        MyCustomCell *cell = [mytableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

        if (cell == nil) 
            cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
        
        MyRowData* data = [tableData objectAtIndex:indexPath.row];
        cell.lb_subject.text = data.subject;
        return cell;
    
    else 
    static NSString *simpleTableIdentifier = @"MyCustomCell";

        MyCustomCell *cell = [mytableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

        if (cell == nil) 
            cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
        
        MyRowData* data = [tableData objectAtIndex:indexPath.row];
        cell.lb_subject.text = data.subject;
        return cell;   

【讨论】:

我以前从未使用过标签。仅使用整数如何工作?我很困惑,因为在 android 中你可以在上面保存对象。 我对安卓一无所知。在 ios 中,您可以从界面生成器或您的代码中为您的表设置标签。它使用整数工作。 我明白了。但是 cell.lb_subject 仍然存在。我想知道为什么你认为标签可以工作。 它在少数情况下对我有用。首先检查您是否正在获取第二个表格的单元格对象? 但我不明白你在哪里设置标签的值。以及为什么要检查 tableView.tag==1【参考方案3】:

我想将单元格注册到 customCell 类中的 tableView 中。像这样的

class func cellForTableView(tableView: UITableView, atIndexPath indexPath: NSIndexPath) -> YourCustomTableViewCell 
let kYourCustomTableViewCellIdentifier = "kYourCustomTableViewCellIdentifier"
tableView.registerNib(UINib(nibName: "YourCustomTableViewCell", bundle: NSBundle.mainBundle()), forCellReuseIdentifier:     kYourCustomTableViewCellIdentifier)

let cell = tableView.dequeueReusableCellWithIdentifier(kYourCustomTableViewCellIdentifier, forIndexPath: indexPath) as! YourCustomTableViewCell

return cell

你可以看到更详细的答案Here。

【讨论】:

仍然失败。现在我遇到了一个异常:由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无法在包中加载 NIB:'NSBundle <...>(已加载)',名称为'MyCustomCell'' 你看我的详细回答了吗? 你用的是xib,我不用。 嗯,你也可以使用 Xib。只需将其用于单元格。休息保持不变。 我已经向我的仓库上传了一个演示 github.com/rchampa/iOS-ReusePrototypeCell【参考方案4】:

我猜你的每个表都有两个原型单元格。

假设表 A - "CustomCellA" & 表 B - "CustomCellB"

两个customCell的父类应该相同。

现在在 cellForRowAtIndexPath 中写下代码,

MyCustomCell *cell;

if (tableView == tableViewA) 
    cell = [mytableView dequeueReusableCellWithIdentifier:@"CustomCellA"];
else
    cell = [mytableView dequeueReusableCellWithIdentifier:@"CustomCellB"];

你的单元格的 Outlet 和属性应该可以在两个 tableview 中找到。

请告诉我结果。

谢谢,希望对你有帮助。

【讨论】:

我有一个故事板。我在表 A 上只定义了一个原型单元格。表 A 加载它的单元格并很好地显示结果。表 B 尝试加载相同的单元格,但它的所有字段都加载为 nil。 您还必须为表 B 定义具有不同标识符的相同原型单元格。您能否分享您的代码,您如何为表 A 定义原型?你使用xib作为单元格吗? @里卡多 是的,我会在几分钟内将演示上传到 github。 我已经向我的仓库上传了一个演示 github.com/rchampa/iOS-ReusePrototypeCell 完成了。您必须在 BViewController 的 tableview 中添加原型。将其命名为 CellB 或任何您喜欢的名称,您可以将其命名为另一个原型标识符,然后在 BViewController 的 tableview cellforrowatindexpath 中更改为“CellB”,即 [tableView dequeueReusableCellWithIdentifier:@"cellB"] @Ricardo【参考方案5】:

您尚未在其他表格中添加单元格 如果您不想为 viewController 2 创建另一个原型单元格,那么您需要使用 XIB

注册您的 XIB:

ViewDidload而不是cellForRow注册您的customcell

[self.tableView registerNib:[UINib nibWithNibName:@"CustomCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"CustomCell"];

和,

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

    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
    if (cell == nil) 
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
        cell = (CustomCell *)[topLevelObjects objectAtIndex:0];
    

    cell.cellLabel.text = _arrData[indexPath.row];

    return cell;

如果您仍然遇到同样的问题,请告诉我

【讨论】:

现在我遇到一个异常:由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无法在包中加载 NIB:'NSBundle <...>(已加载)',名称为'MyCustomCell'' 你重新检查了xib类和单元格标识符的拼写吗?? 是的,我做到了。没有错别字。 我编辑了我的cellForRow 试试这个,请检查你的单元格标识符 bcz 我写CustomCell 你写MyCustomcell 你能显示你的xib截图吗?因为这段代码在我的 x 代码中工作。

以上是关于iOS - dequeueReusableCellWithIdentifier 返回带有 nil 字段的 Cell的主要内容,如果未能解决你的问题,请参考以下文章

DequeueReusableCell 仅在 iPhone 4S 上崩溃应用程序

如何禁用 Tableview DequeueReusableCell?

dequeueReusableCell 之后的单元格布局

如何使用 tableView.dequeueReusableCell 以编程方式将单元格样式添加到单元格?

dequeueReusableCell 打破了cliptobounds

如何在不弄乱内容的情况下标记 dequeueReusableCell?