UICollectionView具有重叠单元格和自定义插入和删除动画

时间:2016-04-04 02:23:10

标签: ios swift uicollectionview uikit

我正在开发一个自定义的UICollectionView + Layout,其中单元格重叠在一起。除此之外,我正在为添加和删除项目实现自定义动画。

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

适当的细胞: Proper cells

插入一些细胞后: Cells with improper z order

这是我自定义插入/删除动画的实现。我的猜测是这些方法存在问题。

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
}

我尝试过的事情:

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

可以在my GitHub找到项目的小型复制品。随意克隆它并玩它。

1 个答案:

答案 0 :(得分:4)

我怀疑,在动画期间,集合视图似乎没有正确应用布局属性。幸运的是,UICollectionViewCell提供了一种实现自定义布局属性的方法:

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

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

我会记录雷达并用链接发表评论。