【问题标题】:Stop Diffable Data Source scrolling to top after refresh刷新后停止 Diffable Data Source 滚动到顶部
【发布时间】:2021-02-19 16:45:51
【问题描述】:

如何在应用快照后停止将视图滚动到顶部的 diffable 数据源。我现在有这个...

    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, PostDetail>()
        snapshot.appendSections([.main])
        snapshot.appendItems(self.userComments)
        self.datasource.apply(snapshot, animatingDifferences: false)
        //self.collectionView.contentOffset = contentOffset
    }

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

【问题讨论】:

  • 除非您最初填充集合视图(仅限第一次),否则不应创建新快照并应用它。您应该从数据源获取快照,对其进行修改并应用它。并且根本不要尝试使用内容偏移量。它只会更新到位。
  • 您好,感谢您的评论,我已经更新了我的代码以向您展示我在做什么。所以我初始化它,然后应用快照。这是基于我下载的苹果示例,这不正确吗?
  • 通过检索当前快照、修改它并在发生变化时应用它,我们将不得不管理两个真实来源,就像我们对 UITableViewDataSource 所做的那样。这样一来,我们将失去 Diffable Data Source 最重要的好处。所以这不是一个好方法。
  • 同意@Amirreza,我认为 Diffable 数据源的目的,至少从它在 WWDC 中的营销方式来看,是您不必担心管理状态。该框架应该能够比较两个数据源并提供开箱即用的动画。我遇到了同样的问题。此外,我正在为不应该动画的单元格传递相同的自定义哈希标识符,但它们是。我以前使用过 IGListKit,所以我知道这不应该是预期的行为。

标签: ios swift diffabledatasource


【解决方案1】:

首先:在大多数情况下,@Amirrezas 的答案将是问题的正确原因。在我的情况下,不是项目,而是导致问题的部分标识符。那是 Hashable 和 Identifiable 具有正确的值,但它是 class,因此从未调用散列函数。我花了一段时间才发现这个问题。更改为结构(因此采用了一些东西;))在我的情况下有所帮助。

这里是 Apple-Dev 论坛上主题的链接作为参考:https://developer.apple.com/forums/thread/657499

希望我的回答对某人有所帮助:)

【讨论】:

    【解决方案2】:

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

    所以总结一下,大体的思路是将具有相同哈希值的项目标识符的实例传递给快照,以告诉 Diffable 数据源这些项目不是新的,不需要删除以前的并插入这些那些。在这种情况下,您不会遇到不必要的滚动。

    【讨论】:

    • 非常感谢 Amirreza,这正是问题所在。我已在 LinkedIn 上向您发送了一条消息。
    猜你喜欢
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多