Swift 4 UICollectionView 检测滚动结束

Posted

技术标签:

【中文标题】Swift 4 UICollectionView 检测滚动结束【英文标题】:Swift 4 UICollectionView detect end of scrolling 【发布时间】:2018-02-09 12:04:49 【问题描述】:

我的应用上有一个HorizontalUICollectionView,当用户在左侧拖动时到达 UICollectionView 的末尾(或接近末尾)时,我想加载更多数据。

我正在使用 Swift 4。我找到了一些 Swift 3 解决方案,但它们对我不起作用。

我当前的代码是:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
    return self.videoViewModel.images.count


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell
    cell.imgImage.image = self.videoViewModel.images[indexPath.row]

    return cell


func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
    updateVideo(data: self.videoViewModel.relatedVideos[indexPath.row])

【问题讨论】:

有多少可见单元格? 从 api 加载数据? 10,首先我加载 10,然后每次滚动条到达最后的某个点时,我都需要再次附加 10。 @McDonal_11 是的,我正在从 api @ivarun 加载数据 【参考方案1】:

您可以使用collection view 的cellForItem 或willDisplayItem 方法。检查是否显示最后一个单元格,并加载您的数据。例如:

斯威夫特:

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) 
     if (indexPath.row == dataSource.count - 1 )  //it's your last cell
       //Load more data & reload your collection view
     

目标-C:

- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath 
    if (indexPath.row == dataSource.count - 1 )  //it's your last cell
       //Load more data & reload your collection view

    

【讨论】:

如果对您的情况没有帮助,请告诉我。 是的,完全正确。但请确保正确处理边缘情况:) 你也可以在 cellForItem 中做同样的事情 是的,我当然会整理出来,放一些布尔值或某事。谢谢。 如果你可以再等 1 秒 :p【参考方案2】:

实现方法scrollViewDidScroll of UIScrollViewDelegate:

var isLoading: Bool = false

 func scrollViewDidScroll(_ scrollView: UIScrollView) 
    let contentOffsetX = scrollView.contentOffset.x
    if contentOffsetX >= (scrollView.contentSize.width - scrollView.bounds.width) - 20 /* Needed offset */ 
        guard !self.isLoading else  return 
        self.isLoading = true
        // load more data
        // than set self.isLoading to false when new data is loaded
    

【讨论】:

我把这个方法放在我的 ViewController 上,我也实现了 UIScrollViewDelegate 但什么也没发生。你可以在gitlab.com/rexhin/ios-kida.git查看我的代码 现在它会触发,但如果我走到最后,它会触发多次,例如 10 或 20 次。 更新了答案 数据加载时你设置isLoading = false了吗? 对不起,我忘了让我试试【参考方案3】:

取一个布尔变量和一个整数变量作为页码,如下所示:

var isDataLoading = false
var pageCount:Int = 1 // Pass this page number in your api

在 cellForItemAt 方法中添加以下代码:

if !isDataLoading && indexPath.row == videoViewModel.count - 1 
            isDataLoading = true
            pageCount += 1
// add you api call code here with pageCount
        

一旦你从 api set isDataLoading bool 获取数据,如下所示:

self.isDataLoading = false

【讨论】:

谢谢,但我对检测滚动结束更感兴趣。【参考方案4】:

这是一个简单的登录,会一直到最后一个索引...!!!

func ScrollEnd() 
          let lastSectionIndex = (self.collectionView?.numberOfSections)! - 1
         let lastItemIndex = (self.collectionView.numberOfItems(inSection: lastSectionIndex)) - 1
           let index =  IndexPath(item: lastItemIndex, section: lastSectionIndex)
           if messages.count != 0
               self.collectionView!.scrollToItem(at: index, at: UICollectionView.ScrollPosition.bottom, animated: false)
               

【讨论】:

【参考方案5】:

将此添加到您的 collectionView willDisplayCell 委托中

if (indexPath.row == dataSource.count - 1 ) 
 //it's your last cell

//Load more data & reload your collection view
  

【讨论】:

以上是关于Swift 4 UICollectionView 检测滚动结束的主要内容,如果未能解决你的问题,请参考以下文章

swift 4 中的 UITableView 和 UICollectionView 部分重复相同的数据

如何在 Swift 4 中为 UICollectionView 的部分设置最大元素数?

如何使用 Alamofire Swift 4 将图像填充到 UICollectionView

Swift 4.0iOS 11 UICollectionView 长按拖拽删除崩溃的问题

如何在UICollectionView Swift 4.0中正确调整和扩展单元格的大小和居中

如何在 UICollectionView Swift 4.0 中正确调整大小和居中扩展单元格