UITableViewCell 内容在单独重新加载单元格时闪烁

UITableViewCell content flickers while reloading cells individually

我有一个链接到 NSFetchedResultController 的 table 视图(即加载数据和跟踪数据更改绑定到 FRC)

我没有在我的单元格中使用 AutoLayout(由于它在 iOS 8 中引入的巨大性能下降)。我在单元格中手动布置单元格的内容(使用 -(void)layoutSubviews)。另外,行高是根据内容计算的,并且 cached/invalidated 正确。

如果与我的数据相关的任何条件发生变化,相关单元格将单独更新(实现整个 -(void)controllerWillChangeContent:...-(void)controllerDidChangeContent:... 委托方法)行更新的动画是:UITableViewRowAnimationNone

这里的问题是,我的单元格有透明背景,我可以看到一些视觉噪音(很可能是实际单元格垂直拉伸,我不能肯定地说,因为它们确实是短暂的)在 [self.tableView reloadRowsAtIndexPaths:...];.

期间

我试了很多都没有用!

以下是我尝试过但不起作用的方法:

有点帮助的东西:

更多信息

其他更多信息

最后,很抱歉我不能分享任何实际代码,因为它不是一个测试项目,而且实现的复杂性使得任何代码共享都是徒劳的,除非作为一个整体来理解。

感谢您的宝贵时间。

如果有人遇到同样的问题:

如果您正在计算单元格高度及其元素,并且您依赖 NSIndexPath 来查询任何数据或条件,请始终检查您的索引路径是否有效(而不是 nil)。 return 索引路径(例如 -(NSIndexPath *)indexPathForCell:.. 等)的大多数 UITableView 方法可能 return nil 值,并且会让你陷入调试视图的螺旋.

在我的例子中,我有一个方法来确定我的单元格是否应该有一个 header,为此我检查了它是第一个单元格还是自上一个单元格以来条件发生了变化。问题是 indexPath.row == 0 是真的,即使索引路径实际上是 nil(这是 Objective-C 中的概念问题,其中 nil 是 0)。所以有那么一小会儿我的细胞会认为它有 header!

我觉得不检查 nil 索引路径有点愚蠢,但我认为分享它可能有一天会对某人有所帮助。

我在使用 reloadRowsAtIndexPath 时也遇到了 UITableViewCell 闪烁的问题,所以我所做的是 -

     [UIView setAnimationsEnabled:NO];
     [self.tableView beginUpdates];

     [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil]
                                               withRowAnimation:UITableViewRowAnimationNone];
     [self.tableView endUpdates];
     [UIView setAnimationsEnabled:YES];

上面的代码片段在重新加载单元格时不会在单元格上显示动画。

我在 swift 中使用它,它减少了闪烁

let visibleIndexs = self.ContentTableview.indexPathsForVisibleRows! as NSArray
        print(visibleIndexs)
        for indx in visibleIndexs {
            if self.imgDownloadedIndexs!.containsObject(indx) {
                  UIView.setAnimationsEnabled(false)
                self.ContentTableview.beginUpdates()
                self.ContentTableview.reloadRowsAtIndexPaths([indx as! NSIndexPath], withRowAnimation:.None)
                self.ContentTableview.endUpdates()
                 UIView.setAnimationsEnabled(true)
                self.imgDownloadedIndexs?.removeObject(indx)

            }

是的,您可以使用 performWithoutAnimation(Swift 版本)

从 @Sandy 的回答中获得类似的结果
UIView.performWithoutAnimation {
      self.tableView.reloadRows(at: [indexPath], with: .none)
}

删除 rowHeightAtIndexPath 方法将解决此问题。确保您已为情节提要中的 table 单元格设置了一些固定高度。

tableView 自定义单元格不可点击且闪烁。这是因为细胞动画。添加以下代码后,单元格可以点击并且工作正常。 这种情况正常发生,也可能发生在运行 UITestCase.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   UIView.performWithoutAnimation {
      self.tableView.reloadRows(at: [indexPath], with: .none)
  }
return cell
}