12

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

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

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

这里的问题是,我的单元格具有透明背景,并且在[self.tableView reloadRowsAtIndexPaths:...];.

我尝试了很多东西都无济于事!

以下是我尝试过但不起作用的事情:

  • 实施-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath,返回估计高度的准确值。
  • 设置self.tableView.rowHeight=UITableViewAutomaticDimension;,有很大帮助,但不能解决它。
  • 禁用动画后[self.tableView beginUpdates];启用[self.tableView endUpdates];
  • 从单元格内容中删除所有子视图-(void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

有一点帮助的事情:

  • 使单元格不透明(即为单元格设置背景颜色)。奇怪的是,工件似乎在实际的单元格内容之下。

更多信息

  • 我的大部分单元格内容都是来自AsyncDisplayKit(ASTextNode、ASImageNode)的节点,但是用它们的UIKit对应项替换它们并不能解决问题。
  • 我所有的视觉更新都发生在主线程上。我总是确保这一点。
  • 这个问题并不普遍,但经常存在。如果有帮助,它们似乎在插入第二个细胞后发生得更多。
  • 在我的单元格中记录该方法-(void)layoutSubviews表明,具有更新条件的单元格在每次更新时连续重新加载 3 次,而其他单元格只更新一次。我不会强迫任何[cell layoutIfNeeded];[cell setNeedsLayout];任何地方。
  • 使用重新加载整个表格视图[self.tableView reloadData];对我来说不是一个选项。

其他更多信息

  • 使单元格不透明会导致单元格只布置一次!奇怪的!

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

谢谢你的时间。

4

6 回答 6

24

在使用 reloadRowsAtIndexPath 时,我也面临同样的 UITableViewCell 闪烁问题,所以我所做的是 -

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

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

重新加载单元格时,上面的代码片段在单元格上没有动画。

于 2015-05-13T21:49:03.770 回答
18

performWithoutAnimation是的,您可以使用(Swift Version)从@Sandy 的回答中获得类似的结果

UIView.performWithoutAnimation {
      self.tableView.reloadRows(at: [indexPath], with: .none)
}
于 2018-01-17T15:53:56.393 回答
6

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

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

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

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

于 2015-04-21T05:40:51.220 回答
3

迅速使用它,它减少了闪烁

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)

            }
于 2016-05-10T13:54:04.443 回答
0

删除 rowHeightAtIndexPath 方法将解决此问题。确保您已为故事板中的表格单元格设置了一些固定高度。

于 2018-10-24T10:54:16.070 回答
-1

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   UIView.performWithoutAnimation {
      self.tableView.reloadRows(at: [indexPath], with: .none)
  }
return cell
}
于 2021-05-19T03:03:07.300 回答