在 cellForRowAtIndexPath 中返回不同的 UITableViewCell 类型

Posted

技术标签:

【中文标题】在 cellForRowAtIndexPath 中返回不同的 UITableViewCell 类型【英文标题】:Return different UITableViewCell types in cellForRowAtIndexPath 【发布时间】:2010-12-09 00:26:58 【问题描述】:

我创建了一个自定义UITableViewCell,按照以下有用的指导从 xib 文件加载它; How do you load custom UITableViewCells from xib files.

我只想要UITableView 中第一行的这个自定义单元格,其他都是简单的标签,标准的UITableViewCell 很好。

问题是当我包含自定义单元格时,整个UITableView 没有显示,并且除了导航元素之外屏幕是空白的。仅使用标准单元格,表格看起来很好,因此它与自定义单元格有关。

这是我必须返回单元格的代码;

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

    if(indexPath.row == 0)  
        ArticleDetailCell *cell = (ArticleDetailCell *)[tableView dequeueReusableCellWithIdentifier:[NSString stringWithFormat:@"%@Detail", reuseIdentifier]];

        if(!cell) 
            // Load the top-level objects from the custom cell XIB.
            NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"ArticleDetailCell" owner:self options:nil];
            // Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
            cell = (ArticleDetailCell *)[topLevelObjects objectAtIndex:0];
        

        [[(ArticleDetailCell *)cell judges] setText:[[self caseBaseArticle] judges]];
        [[(ArticleDetailCell *)cell judgementDate] setText:[[self caseBaseArticle] judgmentDate]];
        [[(ArticleDetailCell *)cell court] setText:[[self caseBaseArticle] court]];

        return cell;

     else     
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];

        if(!cell) 
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier] autorelease];
            [[cell textLabel] setNumberOfLines:1];
            [[cell textLabel] setFont:[UIFont systemFontOfSize:14]];
            [[cell textLabel] setText:articleRowTitles[indexPath.row-1]];
        

        if ([self tableRowHasContentDetail:indexPath]) 
            [self enableTableCell:&cell];
        else 
            [self disableTableCell:&cell];
               

        return cell;
    

ArticleDetailCell 可以从 xib 文件加载,并且属性设置正确,因为我可以在调试器中看到这一点。当我从(gdb) 打印自定义单元格对象时停在return cell 我得到了;

<ArticleDetailCell: 0x4bc22b0; baseClass = UITableViewCell; frame = (0 0; 320 367); autoresize = W+TM+BM; layer = <CALayer: 0x4bc23c0>>

单元格取消引用有问题吗?我仍然会考虑保留计数以及它们何时增加和不增加。

为什么会因为单个单元格的问题,导致整个 UITableView 消失?

编辑:仅供参考@BoltClock

- (void)disableTableCell:(UITableViewCell **)cell 
    [*cell setAccessoryType:UITableViewCellAccessoryNone];
    [*cell setSelectionStyle:UITableViewCellSelectionStyleNone];
    [[*cell textLabel] setTextColor:[UIColor lightGrayColor]];

【问题讨论】:

快速入门:在自定义标签时,在 if 语句中,您不必每次都将 cell 转换为 ArticleDetailCell,因为您已经将其声明并初始化为 ArticleDetailCell .你的 enableTableCell:disableTableCell: 方法是什么样的? @BoltClock 感谢重构提示,在我修复将自定义单元格创建为 UITableViewCell 的问题之前,一定要把它留在里面 @BoltClock 将 disableTableCell 方法添加到问题中(启用几乎相同,但使用不同的值)。 【参考方案1】:

reuseIdentifier 是在哪里定义的?此方法是否始终可用?

【讨论】:

是的,它只是 UIViewController 实现中的一个静态 NSString。【参考方案2】:

问题主要出在自定义单元格的 xib 文件上。严格遵循 Apple 开发者中心的 Loading Custom Cells from NIB Files 就成功了。

关键是将自定义单元格中的File's Owner 设置为我将使用该单元格的UITableViewController 类型。 UITableViewController 还具有用于自定义 UITableViewCellIBOutlet 属性,用于将 File's Owner 连接到 xib 文件中的自定义单元格。

重要的是,在 xib 文件中为 Table View Cell 设置了标识符,以便它与 dequeueReusableCellWithIdentifier 方法中使用的值匹配。

cellForRowAtIndexPath 以这样的方式结束,其中 articleDetailIBOutlet 属性;

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

    if(indexPath.row == 0)  
        ArticleDetailCell  *cell = (ArticleDetailCell *)[tableView dequeueReusableCellWithIdentifier:[NSString stringWithFormat:@"%@Detail",reuseIdentifier]];

        if(!cell) 
            [[NSBundle mainBundle] loadNibNamed:@"ArticleDetailCell" owner:self options:nil];
            cell = articleDetail;
            [self setArticleDetail:nil];
        

        [[cell judges] setText:[[self caseBaseArticle] judges]];
        [[cell judgementDate] setText:[[self caseBaseArticle] judgmentDate]];
        [[cell court] setText:[[self caseBaseArticle] court]];

        return cell;

     else     
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];

        if(!cell) 
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier] autorelease];
            [[cell textLabel] setNumberOfLines:1];
            [[cell textLabel] setFont:[UIFont systemFontOfSize:14]];
            [[cell textLabel] setText:articleRowTitles[indexPath.row-1]];
        

        if ([self tableRowHasContentDetail:indexPath]) 
            [self enableTableCell:&cell];
        else 
            [self disableTableCell:&cell];
               

        return cell;
    

【讨论】:

以上是关于在 cellForRowAtIndexPath 中返回不同的 UITableViewCell 类型的主要内容,如果未能解决你的问题,请参考以下文章

在 cellForRowAtIndexPath 中获取 iOS CoreData 后台线程

UIView 在 cellForRowAtIndexPath 中重叠/再次创建

无法在 cellForRowAtIndexPath 中获取单元格框架或约束

为啥图像未显示在目标 C 的 cellforRowAtIndexPath 中

nib 项目中的 CellForRowAtIndexPath

我应该在 tableView(_:cellForRowAtIndexPath:) 方法中为自定义单元格写啥?