强制 UITableView 为所有单元格调用 cellForRowAtIndexPath:

Posted

技术标签:

【中文标题】强制 UITableView 为所有单元格调用 cellForRowAtIndexPath:【英文标题】:Force UITableView to call cellForRowAtIndexPath: for all cells 【发布时间】:2012-01-21 18:28:54 【问题描述】:

我在使用 UITableView 的 reloadData 方法时遇到了一些问题。我发现只有在添加或删除新单元格时才会调用 cellForRowAtIndexPath。

示例:我有五个单元格,每个单元格包含五个字符串。如果我添加一个新单元格并调用reloadData,表格会更新并且我会看到它。然而,如果我进入五个单元格之一,添加一个新字符串,然后返回并调用reloadData,则不会调用任何表格视图的委托方法。

我的问题:是否可以强制表格视图完全重新加载其所有可见单元格中的数据?

【问题讨论】:

【参考方案1】:

我发现了问题 - 我在 if(cell == nil) 块中有我的单元格自定义代码,所以因为单元格正在回收,所以它们没有被更改。将我的自定义代码从该块中取出可以解决问题。

【讨论】:

您节省了我数小时的精力。谢谢!我不会猜到这个愚蠢的错误:) 很高兴我的解决方案可以帮助其他人!【参考方案2】:

我发现重新加载部分更容易重新加载数据。如果你只有一个部分,你可以试试:

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];

【讨论】:

【参考方案3】:

你可以试试这个

[tableView reloadData];

[tableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade];

把这个放在commitEditingStyle 方法中。

【讨论】:

【参考方案4】:

好吧,表格视图只会在可见单元格上调用cellForRowAtIndexPath,但如果你调用reloadData,它会这样做,所以这里还有其他事情发生,我不确定它是什么。

【讨论】:

在这种情况下,所有单元格都是可见的。我知道数据源(在本例中为 NSUserDefaults)正在更新,所以我不确定为什么只有新单元格被更新。 您是否跟踪了对cellForRowAtIndexPath 的调用以证明它没有被调用,或者您只是没有看到视觉变化?如果cellForRowAtIndexPath 没有被调用......我不知道发生了什么。那时,我会后退一步,追踪对numberOfRowsInSection 的调用。无论如何,我可以说cellForRowAtIndexPath 应该 在您执行reloadData 时为每个可见单元格调用。 NSLogs 说,当我添加新行时,一切都会更新;我最初的假设是错误的。从另一个视图控制器返回表视图时调用 reloadData 时,不会调用任何内容。 您是否明确调用reloadData?它不会因为表格视图再次可见而被自动调用。 是的,我现在还不知道。我怀疑您的程序中存在某些问题,因为该行为听起来不正确,但是直到您找出导致问题的原因,谁知道,这可能是 Apple 错误。不太可能,但并非不可能。【参考方案5】:

即使您的 tableview 有 50 行,也只会存在一次可见的尽可能多的单元格。这就是重用标识符背后的全部故事。因此,不存在强制“所有单元格”。如果出现新单元格,则会动态加载数据。

更改单元格的唯一方法是更改​​由 dataSource 方法 cellForRowAtIndexPath 传递的数据。

【讨论】:

如果您尝试 reloadRowsAtIndexPaths: withRowAnimation: 只是为了检查...不要让这成为解决方案。 您确定您传递给reloadData 的变量此时不为零吗?【参考方案6】:

不要将您的代码从if (cell == nil) 块中取出。相反,为您正在制作的单元格创建一个代表标识符;尝试并确保在标识符中引用了所有单元格的内容。例如,如果您有 3 个数字显示,请确保以唯一的方式在标识符中包含这三个数字,该方式仅引用具有此类内容的单元格。

假设您的类中有三个 NSArray 属性,array1、array2 和 array3,它们的 int 值包装在 NSNumber 对象中。你想使用那些 NSArrays 来填充 UITableView,这就是我要做的:

- (UITableViewCell *)tableView:(UITableView *)tableView 
                     cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    NSString *identifier = [NSString stringWithFormat:@"%@-%@-%@",
                            [[array1 objectAtIndex:indexPath.row] intValue],
                            [[array2 objectAtIndex:indexPath.row] intValue],
                            [[array3 objectAtIndex:indexPath.row] intValue]];
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];

    if (cell == nil) 
        cell = [[[UITableViewCell alloc] 
                                  initWithStyle:UITableViewCellStyleDefault
                                  reuseIdentifier:identifier] autorelease];

        //Build your cell here.
    

    return cell;

【讨论】:

以上是关于强制 UITableView 为所有单元格调用 cellForRowAtIndexPath:的主要内容,如果未能解决你的问题,请参考以下文章

如何强制 uitableview 调整单元格的大小(在停用高度约束后)?

UITableView 重新加载除一个以外的所有单元格

iOS7 UITableView 部分中的最后一个单元格强制全宽分隔符

为 UITableView 插入带有动画的行(并更新所有其他单元格)

UITableView didSelectRowAt indexPath 未在自定义单元格中调用

UITableView insertSections: withRowAnimation: 导致请求所有表格单元格