从上下文菜单中删除UICollectionViewDiffableDataSource项目时出现动画故障

时间:2020-01-20 00:58:28

标签: ios swift diffabledatasource nsdiffabledatasourcesnapshot uicontextmenuconfiguration

我采用了新的UICollectionViewDiffableDataSource。每次删除项目时,我都会应用数据源快照:

var snapshot = NSDiffableDataSourceSnapshot<Int, Item>()
snapshot.appendSections([0])
snapshot.appendItems(items)
apply(snapshot, animatingDifferences: true)

通过内置的收藏夹视图配置选项提供删除:

func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
    guard let item = dataSource.itemIdentifier(for: indexPath) else {
        return nil
    }

    let configuration = UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { _ in
        let delete = UIAction(title: "Delete", image: UIImage(systemName: "trash.fill"), attributes: .destructive) { _ in
            self.deleteItem(item)
        }

        return UIMenu(title: "", image: nil, identifier: nil, children: [delete])
    }
    return configuration
}

如果我从上下文菜单外部删除该项目,则动画效果很好。如果我从上下文菜单中删除,则一个单元消失,然后导致下一个闪烁。我怀疑关闭上下文菜单与运行删除动画之间存在某种冲突。我正在寻找一种解决此问题的方法。

1 个答案:

答案 0 :(得分:0)

编辑:这非常稳定,导致UI冻结和其他奇怪的故障,在某些情况下它有时无法响应长按,因此请勿使用此功能。我希望这个API不会出现故障,这很烦人。

我也发现了这个丑陋的故障,并且非常想放弃,直到我以为实现其他交互API而不是UICollectionView的内置API来尝试一下,奇怪的是动画消失了

首先将互动添加到您的单元格contentView

let interaction = UIContextMenuInteraction(delegate: self)
cell.contentView.addInteraction(interaction)

然后在viewController

中实现委托,大概在您展示单元格的位置
extension ViewController : UIContextMenuInteractionDelegate {
    func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {

        // loop through all visible cells to find which one we interacted with
        guard let cell = collectionView.visibleCells.first(where: { $0.contentView == interaction.view }) else {
            return nil
        }

        // convert it to an indexPath
        guard let indexPath = collectionView.indexPath(for: cell) else {
            return nil
        }

        // continue with your magic!
    }
}

瞧,就是这样,不再出现毛刺的动画。 我不知道是否有一些极端情况会选择错误的单元格或其他怪异的东西,但这似乎很好。