Ios UICollectionView在重新加载数据时无法平滑滚动
在我的UICollectionView中,我使用 self.DataTableCollectionView.reloadData() 但随着我收集的数据越来越多,它的滚动变得粗糙,加载一些页面后,很难向上或向下滚动。它被卡住了 最终,当我尝试一次加载1000行时,滚动工作很顺利,但当我尝试使用API一次分页并加载50行时,滚动就变得很困难 有谁能帮我解决问题吗 我不知道怎么回事?self.DataTableCollectionView.reloadData()是否对此负责 以下是在滚动条上加载数据的代码:Ios UICollectionView在重新加载数据时无法平滑滚动,ios,swift,swift2,uicollectionview,Ios,Swift,Swift2,Uicollectionview,在我的UICollectionView中,我使用 self.DataTableCollectionView.reloadData() 但随着我收集的数据越来越多,它的滚动变得粗糙,加载一些页面后,很难向上或向下滚动。它被卡住了 最终,当我尝试一次加载1000行时,滚动工作很顺利,但当我尝试使用API一次分页并加载50行时,滚动就变得很困难 有谁能帮我解决问题吗 我不知道怎么回事?self.DataTableCollectionView.reloadData()是否对此负责 以下是在滚动条上加载数
func scrollViewDidScroll(scrollView: UIScrollView) {
let offsetY = scrollView.contentOffset.y
let contentHeight = scrollView.contentSize.height
if(offsetY > (contentHeight - scrollView.frame.size.height)){
let seconds = 3.0
let delay = seconds * Double(NSEC_PER_SEC)
let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
self.loadMoreData()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
self.DataTableCollectionView.reloadData()
})
}
}
==========
我把这些细胞重新用作
self.DataTableCollectionView .registerNib(UINib(nibName: "DCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: dCellIdentifier)
self.DataTableCollectionView .registerNib(UINib(nibName: "CCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: cCellIdentifier)
再利用:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let dCell : DCollectionViewCell = collectionView .dequeueReusableCellWithReuseIdentifier(dCellIdentifier, forIndexPath: indexPath) as! DCollectionViewCell
let cCell : ContentCollectionViewCell = collectionView .dequeueReusableCellWithReuseIdentifier(cCellIdentifier, forIndexPath: indexPath) as! CCollectionViewCell
}
=========
添加更具体的代码:
现在我已经更新了我的滚动功能
func scrollViewDidScroll(scrollView: UIScrollView) {
let offsetY = scrollView.contentOffset.y
let contentHeight = scrollView.contentSize.height
if(offsetY > (contentHeight - scrollView.frame.size.height)){
var returnTableData = NSMutableArray()
self.InspectPageId = self.InspectPageId+1
self.dataSource.populateData(PageId:self.InspectPageId)
returnTableData = self.dataSource.DTableDataArray
if(returnTableData.count>0){
for i in 0..<returnTableData.count {
self.TableDataArray.addObject(returnTableData[i])
}
}
self.NumberOfRows = self.TableDataArray.count
dispatch_async(dispatch_get_main_queue(),{
self.DataTableCollectionView.reloadData()
})
}
}
func scrollViewDidScroll(scrollView:UIScrollView){
let offsetY=scrollView.contentOffset.y
让contentHeight=scrollView.contentSize.height
if(offsetY>(contentHeight-scrollView.frame.size.height)){
var returnTableData=NSMutableArray()
self.InspectPageId=self.InspectPageId+1
self.dataSource.populateData(页面ID:self.InspectPageId)
returnTableData=self.dataSource.DTableDataArray
如果(returnTableData.count>0){
对于0中的i..您应该在主线程上调度reloadData()
。根据apple文档,操作UI应该始终在MainThread
中完成。在主队列中重新加载配置
dispatch_async(dispatch_get_main_queue(),{
self.DataTableCollectionView.reloadData()
}
在“出列”单元格后添加以下两行
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
如果self.loadMoreData()
不是异步的,则会阻塞您的UI。
应在主线程上从self.loadMoreData()
调用self.DataTableCollectionView.reloadData()
即使没有阻塞,您也会在每页多次调用loadMoreData()。
您应该添加一个布尔值来检查是否已经在加载数据,我们称之为isLoading
。
初始化viewcontroller时,将isLoading设置为false。
在self.loadMoreData()
中将其设置为true,并更改签入scrollViewDidScroll(scrollView:UIScrollView)
使其看起来像这样:
if(offsetY > (contentHeight - scrollView.frame.size.height)) && !isLoading{
self.loadMoreData()
}
尝试将重新加载collectionview从scrollviewdidscroll移动到loadmoredata()
func loadmoredata(){
/*
1.清单项目
2.然后在末尾调用realoadata
3.如果您的单元格中有图像,则使用图像缓存,您可以编程图像缓存或使用类似的库
*/
dispatch\u async(dispatch\u get\u global\u queue(dispatch\u queue\u PRIORITY\u DEFAULT,0),{self.DataTableCollectionView.reloadData()})
}您应该只从主线程更新UI,所以改为这样做
Swift 2.x:
dispatch_async(dispatch_get_main_queue()), {
self.DataTableCollectionView.reloadData()
}
DispatchQueue.main.async {
self.DataTableCollectionView.reloadData()
}
dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)){
self.loadMoreData()
}
DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {
self.loadMoreData()
}
Swift 3:
dispatch_async(dispatch_get_main_queue()), {
self.DataTableCollectionView.reloadData()
}
DispatchQueue.main.async {
self.DataTableCollectionView.reloadData()
}
dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)){
self.loadMoreData()
}
DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {
self.loadMoreData()
}
如果这不能解决问题,那么您可能还需要在后台线程上调用loadMoreData()
Swift 2.x:
dispatch_async(dispatch_get_main_queue()), {
self.DataTableCollectionView.reloadData()
}
DispatchQueue.main.async {
self.DataTableCollectionView.reloadData()
}
dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)){
self.loadMoreData()
}
DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {
self.loadMoreData()
}
Swift 3:
dispatch_async(dispatch_get_main_queue()), {
self.DataTableCollectionView.reloadData()
}
DispatchQueue.main.async {
self.DataTableCollectionView.reloadData()
}
dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)){
self.loadMoreData()
}
DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {
self.loadMoreData()
}
由于您没有向我们展示您的loadMoreData()
函数,因此不清楚您的代码到底是如何工作的。实际上,您可能想调用DataTableCollectionView.reloadData())
从内部loadMoreData
,但如果不查看函数,我无法判断。请添加其他代码是否重用collectionview单元格?是的,我正在重用collectionview。我在问题中添加了代码。是否缓存图像?您仍然没有添加“loadMoreData()'函数,您从'scrollViewDidScroll'中删除了对'loadMoreData()'的调用是的,我已经更新了我的问题,我已经附加了更新的“scrollViewDidScroll()”函数,现在没有更多的“loadMoreData()”函数,loadMoreData()函数的代码添加到了“scrollViewDidScroll()”中函数我添加了这两行和以及collectionview的预取方法。感谢buddy的回答。:)