UICollectionView具有重叠的单元格和自定义插入和删除动画 [英] UICollectionView with overlapping cells and custom insertion and deletion animations

查看:397
本文介绍了UICollectionView具有重叠的单元格和自定义插入和删除动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理自定义UICollectionView +布局,其中单元格相互重叠.最重要的是,我正在实现自定义动画以添加和删除项目.

I'm working on a custom UICollectionView + Layout where the cells overlap on top of each other. On top of this, I'm implementing custom animations for the addition and removal of items.

一切正常,除了在插入/删除项目时属性的zIndex属性似乎被忽略之外.

Everything's working fine, except the zIndex property of the attributes seem to be ignored during insertion/deletion of items.

正确的单元格:

插入一些单元格后:

After inserting some cells:

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

Here's my implementation for custom insertion/deletion animations. My guess is the problem is somewhere in these methods.

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设置为其最终值.
  • 使集合视图手动设置为动画后的单元格排序(这很不客气,我想避免这种情况,因为它有时会引起一些奇怪的行为).
  • 调用super.initialLayoutAttributes...等并修改从中返回的属性.这样做的问题是,当插入一个新的单元格时,它不能处理其他单元格的移动.而是细胞淡入淡出.
  • Setting the zIndex in the initialLayoutAttributes... method to the value it will end up being.
  • Making the collection view manually reorder the cells after the animation (which is pretty hacky, and I'd like to avoid this, since it can cause some weird behaviour sometimes).
  • Calling super.initialLayoutAttributes... etc and modifying the attributes returned from that. The issue with that is it does not handle the other cells shifting when a new one is inserted; instead the cells fade in and out.

可以在我的GitHub 上找到该项目的小型复制者.随意克隆它并玩弄它.

A small reproducer of the project can be found on my GitHub. Feel free to clone it and play around with it.

推荐答案

正如我所怀疑的那样,似乎集合视图在动画期间未正确应用布局属性.幸运的是,UICollectionViewCell为您提供了一种实现自定义布局属性的方法:

As I suspected, it seems the collection view is not properly applying the layout attributes during the animation. Luckily, UICollectionViewCell provides a method for you to implement custom layout attributes:

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

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

Adding the above code results in the inserted cell appearing at the correct zIndex.

我将记录雷达并通过链接发表评论.

I'll log a radar and comment with the link.

这篇关于UICollectionView具有重叠的单元格和自定义插入和删除动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆