UICollectionView 插入动画单元格立即出现,后面跟着实际的动画单元格

Posted

技术标签:

【中文标题】UICollectionView 插入动画单元格立即出现,后面跟着实际的动画单元格【英文标题】:UICollectionView Insert animation cell appears immediately followed by the actual animated cell 【发布时间】:2014-07-01 21:17:45 【问题描述】:

我为集合视图编写了自定义布局。集合视图的一部分涉及在顶部插入新项目,动画从屏幕外开始。为了做到这一点,我使用了通常的 initialLayouts 方法。我能够正确地为对象设置动画,但似乎有一个我无法解决的奇怪问题。

我正在制作动画的单元格立即出现在其最终位置,然后第二个单元格从预期的屏幕外位置动画到位,动画完成后消失。我所有其他用于删除、边界更改等的动画都很好,所以我不相信我的布局缓存是错误的,正常布局是完美的。这可能是单元重用问题?

我制作了一个演示问题的快速视频(插入从 7 秒开始)http://cl.ly/WMei

以前有没有人见过这种行为并且可以指出正确的方向?

不幸的是,我无法共享整个布局类,但是这里是我的 layoutAttributes 方法和初始插入属性,我可以尝试在需要时提供更多信息。我很欣赏这是一个很难调试的问题,所以非常感谢您花时间检查它:)。

以下是我为顶部插入应用的属性:

  MCLTXGridLayoutAttributes *att = [(MCLTXGridLayoutAttributes*)[self.dataStructure itemAtIndexPath:itemIndexPath] copy];
  att.alpha = 1.0;
  CGRect newFrame = att.frame;
  newFrame.origin.y = self.collectionView.bounds.origin.y - att.totalHeight;
  att.frame = newFrame;
  return att;

以及布局属性方法:

    - (UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath

  MCLTXGridLayoutAttributes *att = [MCLTXGridLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
  CGFloat randomTopPadding = (arc4random() % kMaxVerticalSpacing);
  randomTopPadding += kMinVerticalSpacing;
  NSInteger randomExtraPadding = (NSInteger)arc4random() % kOneInXChanceOfRecievingExtraPadding;
  att.topPadding = randomTopPadding + (randomExtraPadding == 1 ? kItemRandomExtraPadding : 0);

  NSUInteger column = [self.dataStructure indexForShortestColumn];
  att.columnIndex = column;

  CGFloat y = MAX(self.tmpCachedHeight, [self.dataStructure heightForColumnWithIndex:column] + kMinItemSpacing) + att.topPadding;

  CGFloat height = [self.datasource collectionView:self.collectionView heightForItemAtIndex:indexPath];
  CGRect frame = CGRectMake([self xOriginForColumn:column], y, self.cachedColumnWidth, height);
  att.frame = frame;
  att.layerPriority = [self.datasource collectionView:self.collectionView layerPriorityForItemAtIndexPath:indexPath];
  att.zIndex = att.layerPriority * -10;
  att.transform3D = CATransform3DIdentity;
  att.transform = CGAffineTransformIdentity;
  return att;

【问题讨论】:

有没有想过这个?有类似的问题 @RyanPoolos 请参阅下面的答案 - 希望它至少可以为您指明正确的方向! 不怕那不是我们的问题。我们投入了更多的时间,发现这是 UICollectionView 的渲染管道的问题。它拒绝为在帧外开始或结束动画的单元格设置动画。可能是优化失控了。感谢您的回复。 这似乎有点奇怪 - 我们的集合视图布局完全没有问题。它不是流布局的子类,因为它是优化所在。如果帧修改不起作用,那么也许可以尝试转换转换,因为最终结果应该看起来相同。祝你好运! 它是一个自定义布局。我已经使用简单的彩色块在一个孤立的项目中复制了它。但我会尝试转换!这是个好主意! 【参考方案1】:

我最终还是明白了这一点。我们使用的是 Magical Record,但问题在于保存。

在我的测试中,我正在创建假对象并使用后台线程进行保存,就像您应该对 MR 所做的那样。问题出在我们的网络代码中,完全不小心在主线程上下文中调用了 write + save。这是一个很小的写入,但足以扰乱渲染并导致视觉重影效果。

如果您遇到此问题,并且您正在使用诸如 Magical Record 或多线程核心数据以及获取的结果控制器之类的东西,那么请仔细检查您的保存调用,以确保您没有意外碰到主线程。

【讨论】:

以上是关于UICollectionView 插入动画单元格立即出现,后面跟着实际的动画单元格的主要内容,如果未能解决你的问题,请参考以下文章

你如何设置 UICollectionView 动画的持续时间?

UICollectionView 单元格展开动画问题

单元格删除时的 UICollectionView 动画

在 UICollectionView 单元格中停止动画

UICollectionView:重新加载数据,不删除单元内动画

UICollectionView 单元格没有动画运动