UITableViewCell可重用性导致问题[与图像]!

时间:2011-07-12 19:19:36

标签: iphone objective-c cocoa-touch uitableview

一张图片胜过千言万语,我猜测下面张贴的图片清楚地表达了我现在面临的问题。

这是一个小小的总结:

我创建了一个tableView,每个tableViewCell都有一个textField作为子视图。我向上和向下滚动,我的视图搞砸了。我猜这是因为Cell Reusability。但我需要帮助。

注意此问题不是因为按钮或屏幕底部的uitextView。如果我没有它们,并且我只有前三个部分,则textFields会被移位并且会混淆几个单元格的textFields。还要注意图像4中的textField偏移与其他图像相比。代码粘贴在此处 http://www.pastie.org/2203340

**P.S.:**   I have added the solution to the problem at the end of the question. 

这是我的常规观点

enter image description here

这是我向下滚动(见下图)

enter image description here

经过几次向上和向下滚动...(见下文) enter image description here

经过几次滚动......(见下文) enter image description here

解决方案:

我非常感谢@caleb和其他人指出我正确的方向并帮助我解决这个问题。对于那些也面临同样问题的人,我想我应该提供一个简短而又甜蜜的答案。

将UITableViewCells与不同的CellIdentifier配合使用。这样可以确保不会调用相同的单元格。

3 个答案:

答案 0 :(得分:9)

您猜测它与细胞重用有关是正确的。我注意到的第一件事是你为所有细胞使用相同的细胞标识符。这意味着所有单元格都被认为是相同的,您应该假设每次都必须配置关于单元格的所有。对不同类型的细胞使用不同的标识符会更容易,但我会让你稍微咀嚼一下......

无论如何,问题的根源是这段代码:

if (section ==3){
    cell =nil;
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    if (indexPath.row ==0){
        cell.backgroundColor = [UIColor clearColor];
        cell.contentMode = UIViewContentModeScaleToFill;
        [cell.contentView addSubview:self.footerView];
    }
}

对于这个特定的单元格,您要设置背景颜色以清除,添加footerView等。但是您没有为任何其他单元格设置背景颜色,所以只要这个特定的单元格恰好是在不同的位置重复使用,你将获得明确的背景和其他修改。

现在,您可能更容易理解为什么您可能希望为不同类型的单元格使用不同的单元格标识符。如果您使用与透明细胞不同的透明细胞标识符,则不必担心透明细胞被回收为白细胞,反之亦然。您应该为每个“单元格类型”使用不同的标识符,其中“单元格类型”由您不希望每次重复使用单元格时配置的所有单元属性定义。

您在-reuseTableViewCellWithIdentifier:withIndexPath:方法中做了大量工作,最终导致单元格无法重复使用。相反,您应该识别要显示的单元格的每个不同“类型”或“样式”,与其中显示的特定信息无关。例如,前三个部分中的所有单元格看起来大致相同:它们都与UITableViewCellStyleValue1标准单元格样式相似,只是细节标签留空并且文本字段添加到右边。然后,对所有这些单元使用相同的重用标识符。 -reuseTableViewCellWithIdentifier:withIndexPath:实际上不应该关心索引路径 - 它应该只创建并返回所提供的重用标识符所确定的所需样式的单元格。保留将这些单元格中的字段文本设置为-tableView:cellForRowAtIndexPath:方法的工作。

我注意到在创建每个单元格时,您正在存储索引路径和指向文本字段的指针。如果您重复使用单元格,这些都不会有任何帮助。

如果你永远不会在桌面上添加比你所展示的单元格更多的单元格,那么简单地跳过整个重复使用的东西可能更简单。当在具有数十个或数百个单元格的表格中滚动时,重用单元格可以显着提高性能,但是如果您将永远不会有超过十个或十五个单元格,并且其中一半在任何给定时间都在屏幕上,则重用的优势细胞不是很好。不过,我鼓励你花时间去理解这个想法;迟早你会想要创建一个包含很多行的表。

答案 1 :(得分:1)

我之前也经历过这种情况。尝试为每种类型创建一个新单元格。这样,包含文本字段的单元格不会仅用于标题单元格。

答案 2 :(得分:0)

解决此问题的一种方法是在cellForRowAtIndexPath方法中将所有单元格设置为nil。这样可以确保每个都是新绘制的,而不会像图片中那样覆盖某些内容。缺点是它对系统来说是额外的工作,不能像他们想做的那样重复使用单元格