Uitableview TableView单元格重复使用和不需要的复选标记-这让我很痛苦

Uitableview TableView单元格重复使用和不需要的复选标记-这让我很痛苦,uitableview,reusability,checkmark,Uitableview,Reusability,Checkmark,苹果的iOSTableView和手机的重复使用正在折磨着我。我搜索了又搜索又研究,但找不到好的文档或好的答案。问题在于,当TableView重用单元格时,在所选单元格上设置的复选标记(单元格附件)等内容会在表视图中较低的单元格中重复。我知道,由于内存限制,单元重用是按设计进行的,但是如果你有一个包含50个项目的列表,并且它开始在不需要的地方设置额外的复选标记,这会使整个工作毫无用处 我要做的就是在我选择的单元格上设置一个复选标记。我使用自己的自定义单元格类和由boiler plate Table


苹果的iOS
TableView
和手机的重复使用正在折磨着我。我搜索了又搜索又研究,但找不到好的文档或好的答案。问题在于,当
TableView
重用单元格时,在所选单元格上设置的复选标记(单元格附件)等内容会在表视图中较低的单元格中重复。我知道,由于内存限制,单元重用是按设计进行的,但是如果你有一个包含50个项目的列表,并且它开始在不需要的地方设置额外的复选标记,这会使整个工作毫无用处

我要做的就是在我选择的单元格上设置一个复选标记。我使用自己的自定义单元格类和由boiler plate TableView类生成的标准单元格尝试了这一点,但结果总是一样的

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

我甚至尝试过为每个细胞使用真正唯一的细胞标识符。因此,我使用了一个静态int,将其转换为一个字符串,使单元格得到@“cell1”@“cell2”等。在测试过程中,我可以看到在滚动过程中生成的数百个新单元格,即使表格只有30个项目

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

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


有没有人想出了一个优雅的解决办法来解决这种恼人的行为?

细胞重复使用可能很棘手,但你必须记住两件事:

  • 对一种类型的单元格使用一个标识符-只有在一个表视图中使用不同的UITableViewCell子类,并且必须依赖它们对不同单元格的不同行为时,才真正需要使用多个标识符
  • 您重用的单元可以处于任何状态,这意味着您必须再次配置单元的各个方面,尤其是检查mars/images/text/accessoryViews/accessoryTypes等等
您需要做的是为您的复选标记状态创建一个存储—一个包含bools的简单数组(或分别包含boolean 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

谢谢你的建议,马丁。我将尝试一下,尽管它看起来确实像是TouchCell项目中的代码与DevCenter(苹果代码)的一个变体。它们使用字典类来存储布尔值和单元格文本。它只对几个电池(9个或10个)起作用,但当电池被重复使用20到30个或更多时间时,它会以同样的方式发生故障。。。顺便说一句,今天早些时候我试着通过仪器运行一个测试应用程序,在这个程序中我根本不重用细胞,而且它实际上比首选方法使用的内存更少。(如果我理解正确的话!)我没有仔细看他们的代码,但很可能他们看起来很相似,因为这就是你想要的方式。也许你应该把你的代码上传到某个地方,然后把链接作为评论贴在这里。我只是制作一个单一的查看应用程序来尝试你的建议。我将创建两个可静音数组,一个用于显示数据(NSString值),另一个用于BOOL状态,如您所建议的。是否使用多个节?。。如果没有代码,我想我们不能为你做更多:(我会发布一些结果,马丁。我只是想写一些代码,同时做一些食物。你不在丹麦,是吗?