UICollectionView与重叠单元格和自定义插入和删除animation
我正在处理一个自定义的UICollectionView +布局,其中的单元格重叠在一起。 最重要的是,我正在实现添加和删除项目的自定义animation。
一切工作正常,除了插入/删除项目时,属性的zIndex
属性似乎被忽略。
合适的细胞:
插入一些单元格后:
这是我的自定义插入/删除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一个雷达,并评论链接。