我正在尝试使用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
语句。设置断点。
答案 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
。
未调用预取的原因是因为已经加载了每个单元。没有任何东西在预取中了。因为您的集合视图同时显示每个单元格。
如果要滚动集合视图...让集合视图处理它。您不需要将集合视图放在另一个滚动视图中。