UICollectionView的prefetchItems未被调用

时间:2018-05-15 07:49:52

标签: swift uicollectionview

我正在尝试使用UICollectionView协议为UICollectionViewDataSourcePrefetching实现数据预取;但是,没有调用相应的方法 集合视图有custom layout。我也尝试过常规流程布局,结果相同。
在重新加载数据时,我执行以下代码以使集合视图具有其内容的大小,以防止在该集合视图中滚动但在集合视图外的滚动视图中:

func reloadData() {
    viewDidLayoutSubviews()
    collectionView.reloadData()
    collectionView.layoutIfNeeded()
    viewDidLayoutSubviews()
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    collectionViewHeightConstraint.constant = collectionView.collectionViewLayout.collectionViewContentSize.height
    collectionView.layoutIfNeeded()
    view.layoutIfNeeded()
}

也许这与它有关?

我做了什么:

  • 我的UIViewController 确实继承自UICollectionViewDataSourcePrefetching
  • collectionView.prefetchDataSource = self(也尝试使用故事板)
  • collectionView.isPrefetchingEnabled = true(也尝试使用故事板)
  • 我已实施collectionView(_:prefetchItemsAt:)

问题:

未调用prefetchItemsAt方法。我确定通过在方法&中放置print语句。设置断点。

2 个答案:

答案 0 :(得分:1)

就像评论中所要求的那样,我将在此处分享我对此问题的实施:

我创建了跟踪器prefetchState,该跟踪器确定我目前是否正在预取:

enum PrefetchState {
    case fetching
    case idle
}
var prefetchState: PrefetchState = .idle

然后,我将滚动视图的委托(集合视图所在的滚动视图)连接到我的视图控制器,并实现了scrollViewDidScroll方法:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    guard scrollView == self.scrollView else { return }

    let prefetchThreshold: CGFloat = 100 // prefetching will start 100pts above the bottom of the scroll view
    if scrollView.contentOffset.y > scrollView.contentSize.height-screenBounds.height-prefetchThreshold {
        if prefetchState == .idle {
            prefetchItems()
        }
    }
}

在那里,您可以看到我正在检查我们是否已经预取。如果没有,我打电话给prefetchItems(),如下所示:

func prefetchItems() {
    guard prefetchState == .idle else { return }
    prefetchState = .fetching
    someDownloadFuncWithCompletionBlock { (newItems) in
        self.dataSource += newItems
        self.collectionView.reloadData()
        self.prefetchState = .idle
    }
}

答案 1 :(得分:0)

  

我执行以下代码,使集合视图具有其内容的大小,以防止在该集合视图中滚动但在集合视图外的滚动视图中滚动:

听起来很破碎。

你为什么这样做?

当用户滚动集合视图时,将触发对集合视图(来自文档)的预取。通过使集合视图框架与内容大小相同,您实际上禁止滚动集合视图本身。

  

当用户滚动

时,集合视图会调用此方法

如果您强制集合视图框架与内容大小相同,那么您将完全打破UICollectionView

未调用预取的原因是因为已经加载了每个单元。没有任何东西在预取中了。因为您的集合视图同时显示每个单元格。

如果要滚动集合视图...让集合视图处理它。您不需要将集合视图放在另一个滚动视图中。