刷新后停止“可扩散数据源”滚动到顶部

问题描述

应用快照后,如何停止可扩散数据源将视图滚动到顶部。我目前有这个...

    fileprivate func configureDataSource() {
        self.datasource = UICollectionViewDiffableDataSource<Section,PostDetail>(collectionView: self.collectionView) {
            (collectionView: UICollectionView,indexPath: IndexPath,userComment: PostDetail) -> UICollectionViewCell? in
            guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PostDetailCell.reuseIdentifier,for: indexPath) as? PostDetailCell else { fatalError("Cannot create cell")}
            
            cell.user = self.user
            cell.postDetail = userComment
            cell.likeCommentDelegate = self
            return cell
        }
        
        var snapshot = NSDiffableDataSourceSnapshot<Section,PostDetail>()
        snapshot.appendSections([.main])
        snapshot.appendItems(self.userComments)
        self.datasource.apply(snapshot,animatingDifferences: true)
    }

    fileprivate func applySnapshot() {

        //let contentOffset = self.collectionView.contentOffset
        var snapshot = NSDiffableDataSourceSnapshot<Section,animatingDifferences: false)
        //self.collectionView.contentOffset = contentOffset
    }

存储偏移量,然后重新应用它。有时它会完美运行,有时视图会跳动。有更好的方法吗?

解决方法

此问题的根源可能是您的商品标识符类型,即UserComment。 Diffable数据源使用您的项目标识符类型的哈希值来检测它是当前表示的新实例还是旧实例。 如果您手动实现哈希协议,并且使用了每次初始化该类型的新实例时都会生成的UUID,则会误导Diffable数据源,并告诉它这是项标识符的新实例。因此,必须删除以前的那些,并代表新的。这将导致表或集合视图在应用快照后滚动。 为解决将uuid替换为您知道的唯一类型的属性之一或更普遍的做法,请使用一种为相同实例生成相同哈希值的技术。

因此,总而言之,一般的想法是将具有相同哈希值的项目标识符的实例传递给快照,以告知Diffable数据源这些项目不是新项目,无需删除先前的项目并将其插入那些。在这种情况下,您不会遇到不必要的滚动。