UICollectionView与重叠单元格和自定义插入和删除animation

我正在处理一个自定义的UICollectionView +布局,其中的单元格重叠在一起。 最重要的是,我正在实现添加和删除项目的自定义animation。

一切工作正常,除了插入/删除项目时,属性的zIndex属性似乎被忽略。

合适的细胞: 合适的细胞

插入一些单元格后: 不正确的z顺序的单元格

这是我的自定义插入/删除animation的实现。 我的猜测是问题在这些方法的某处。

 override func initialLayoutAttributesForAppearingItemAtIndexPath(itemIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? { let attributes = layoutAttributesForItemAtIndexPath(itemIndexPath) for updateItem in updateItems { switch updateItem.updateAction { case .Insert: if updateItem.indexPathAfterUpdate == itemIndexPath { let translation = collectionView!.bounds.height attributes?.transform = CGAffineTransformMakeTranslation(0, translation) break } default: break } } return attributes } override func finalLayoutAttributesForDisappearingItemAtIndexPath(itemIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? { for updateItem in updateItems { switch updateItem.updateAction { case .Delete: if updateItem.indexPathBeforeUpdate == itemIndexPath { let attributes = layoutAttributesForItemAtIndexPath(itemIndexPath) let translation = collectionView!.bounds.height attributes?.transform = CGAffineTransformMakeTranslation(0, translation) return attributes } case .Move: if updateItem.indexPathBeforeUpdate == itemIndexPath { return layoutAttributesForItemAtIndexPath(updateItem.indexPathAfterUpdate!) } default: break } } let finalIndex = finalIndexForIndexPath(itemIndexPath) let shiftedIndexPath = NSIndexPath(forItem: finalIndex, inSection: itemIndexPath.section) return layoutAttributesForItemAtIndexPath(shiftedIndexPath) } private func finalIndexForIndexPath(indexPath: NSIndexPath) -> Int { var newIndex = indexPath.item for updateItem in updateItems { switch updateItem.updateAction { case .Insert: if updateItem.indexPathAfterUpdate!.item <= newIndex { newIndex += 1 } case .Delete: if updateItem.indexPathBeforeUpdate!.item < newIndex { newIndex -= 1 } case .Move: if updateItem.indexPathBeforeUpdate!.item < newIndex { newIndex -= 1 } if updateItem.indexPathAfterUpdate!.item <= newIndex { newIndex += 1 } default: break } } return newIndex } 

我试过的东西:

  • initialLayoutAttributes...方法中的zIndex设置为最终的值。
  • 手动制作集合视图会在animation之后对单元格进行重新sorting(这很不方便,我想避免这种情况,因为它有时会导致一些奇怪的行为)。
  • 调用super.initialLayoutAttributes...等,并修改从那里返回的属性。 这个问题是,当插入一个新的单元格时,它不处理其他的单元格移动; 而是细胞淡入淡出。

项目的一个小复制品可以在我的GitHub上find 。 随意克隆它,并玩它。

正如我怀疑,似乎集合视图不正确应用布局属性在animation过程中。 幸运的是, UICollectionViewCell为您提供了实现自定义布局属性的方法:

 override func applyLayoutAttributes(layoutAttributes: UICollectionViewLayoutAttributes) { layer.zPosition = CGFloat(layoutAttributes.zIndex) } 

添加上面的代码会导致插入的单元格出现在正确的zIndex处。

我会logging一个雷达,并评论链接。