11


Apple 的 iOSTableView和 cell 重用让我快要死了。我搜索、搜索和研究,但找不到好的文档或好的答案。问题是,当TableView重用单元格时,在选定单元格上设置的复选标记(单元格附件)之类的东西会在表格视图中更下方的单元格中重复。我知道由于内存限制,单元重用是设计使然,但是如果您有一个包含 50 个项目的列表,并且它开始在不需要的地方设置额外的复选标记,这会使整个努力毫无用处。

我要做的就是在我选择的单元格上设置一个复选标记。我已经尝试过使用我自己的自定义单元格类和由样板 TableView 类生成的标准单元格,但它总是以相同的方式结束。

Apple 甚至有一个名为 TouchCell 的示例项目,您可以从开发中心下载,它应该显示使用左侧带有图像控件的自定义单元格设置复选标记的不同方式。该项目使用字典对象作为数据源而不是可变数组,因此每个项目都有一个字符串值和布尔检查值。这个布尔检查值应该设置复选标记,以便它可以跟踪选定的项目。只要您使用 15 个以上的单元格填充 TableView,此示例项目也会显示这种愚蠢的行为。单元格的重用开始设置不需要的复选标记。

我什至尝试过为每个单元格使用真正唯一的单元格标识符。所以不是每个单元格都有类似@“Acell”的东西,我使用了一个静态int,转换为一个字符串,所以单元格得到@“cell1”,@“cell2”等。虽然在测试过程中,我可以看到数百个新单元格在哪里在滚动期间生成,即使表格只有 30 个项目。

它确实解决了复选标记重复问题,但我怀疑内存使用率太高了。

就好像当前不在表格的可视区域中的单元格在它们被滚动回视图时被重新创建。

有没有人想出一个优雅的解决方案来解决这种恼人的行为?

4

1 回答 1

17

单元重用可能很棘手,但您必须牢记两件事:

  • 为一种类型的单元格使用一个标识符- 仅当您在一个表格视图中使用不同的 UITableViewCell 子类并且您必须依赖它们对不同单元格的不同行为时才需要使用多个标识符
  • 您重用的单元格可以处于任何状态,这意味着您必须重新配置单元格的各个方面 - 尤其是 checkmars/images/text/accessoryViews/accessoryTypes 等

您需要做的是为您的复选标记状态创建一个存储 - 一个包含布尔值的简单数组(或分别包含布尔 NSNumber 对象的 NSArray )应该可以做到这一点。然后,当您必须创建/重用单元格时,请使用以下逻辑:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *reuseIdentifier = @"MyCellType";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    if(cell == nil) {
        /* create cell here */
    }
    // Configure cell now
    cell.textLabel.text = @"Cell text"; // load from datasource
    if([[stateArray objectAtIndex:indexPath.row] boolValue]) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }
    return cell;
}

那么你将不得不对水龙头做出反应:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [stateArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:![[stateArray objectAtIndex:indexPath.row] boolValue]]];
    [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}

只要记住NSMutableArray用于您的数据存储;)

于 2011-06-11T14:32:20.037 回答