应用 NSDiffableDataSourceSnapshot 时,ViewController 中的 UICollectionView 拉取刷新跳转

Posted

技术标签:

【中文标题】应用 NSDiffableDataSourceSnapshot 时,ViewController 中的 UICollectionView 拉取刷新跳转【英文标题】:Pull to refresh for UICollectionView in ViewController jumps when applying NSDiffableDataSourceSnapshot 【发布时间】:2021-03-14 15:04:26 【问题描述】:

我已将 UICollectionView 作为子视图添加到我的 ViewController。我还为 UICollectionView 设置了 UIRefreshControl,当我下拉刷新时它会应用 NSDiffableDataSourceSnapshot。应用快照时动画会跳转(请注意,即使导航栏标题不大也会发生这种情况。)

这里是相关的sn-ps代码

var collectionView: UICollectionView! = nil
var dataSource: UICollectionViewDiffableDataSource<Section, Item>! = nil

override func viewDidLoad() 
    super.viewDidLoad()
    
    let collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: 
    generateLayout())
    view.addSubview(collectionView)
    collectionView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
    collectionView.backgroundColor = .systemGroupedBackground
    self.collectionView = collectionView
    collectionView.delegate = self

    let refreshControl = UIRefreshControl()
    refreshControl.addTarget(self, action: #selector(doSomething), for: .valueChanged)
    collectionView.refreshControl = refreshControl

    
@objc func doSomething(refreshControl: UIRefreshControl) 
    DispatchQueue.main.async 
        var dataSourceSnapshot = NSDiffableDataSourceSnapshot<Section, Item>()
        // add data
        dataSource.apply(dataSourceSnapshot)
    
    refreshControl.endRefreshing()

我是否可以进行任何更改以应用快照而不会突然跳转?

【问题讨论】:

【参考方案1】:

很遗憾,自 ios 6 以来,Apple 工程师无法正确解决该问题。

长话短说:您不想在滚动视图时endRefreshing isTrackingUIRefreshControl修改了scrollView的contentInsetcontentOffset,总是会造成这样的跳转。

如果您在任何地方都有网络请求状态,或者任何其他指示正在加载的标志,您可以简单地这样做:

@objc func doSomething(refreshControl: UIRefreshControl) 
    loading = true
    DispatchQueue.main.async 
        var dataSourceSnapshot = NSDiffableDataSourceSnapshot<Section, Item>()
        // add data
        dataSourceSnapshot.appendSections([.test])
        dataSourceSnapshot.appendItems([.test])
        self.dataSource.apply(dataSourceSnapshot)
        self.loading = false
        
    


override func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) 
    if !loading && collectionView.refreshControl!.isRefreshing 
        collectionView.refreshControl!.endRefreshing()
    

我不太喜欢 loading 这样的标志,但这只是一个例子。希望您有更好的事实来源表明某些“工作”是否仍在进行中。

我想可能有更好的解决方法(通过在运行时修补类),但通常需要时间来调查。我想知道该解决方案是否满足您的需求。

【讨论】:

以上是关于应用 NSDiffableDataSourceSnapshot 时,ViewController 中的 UICollectionView 拉取刷新跳转的主要内容,如果未能解决你的问题,请参考以下文章

Windows 应用商店应用标准样式与 Windows 应用商店应用字体指南

向应用添加应用内购买会影响已购买该应用的用户吗?

应用商店拒绝应用后如何再次上传应用

通过应用内购买付费应用到免费应用

删除应用扩展后仍然出现应用安装失败错误 - 此应用包含具有非法捆绑标识符的应用扩展

将应用程序提交到应用程序商店是不是需要应用程序 url