检查单元格是否完全显示在collectionview中

时间:2018-10-30 01:03:42

标签: ios swift uiscrollview uicollectionview uicollectionviewcell

我有一个集合视图,其中单元格的大小恰好等于collectionView的大小,因此每个单元格应占据整个屏幕。我实现了一项功能,每当在滚动中拖动或减速单元格时,该单元格便会捕捉到完整视图。 UX就是这样的。

https://drive.google.com/open?id=1v8-WxCQUzfu8V_k9zM1UCWsf_-Zz4dpr

我想要什么:

从剪辑中您可以看到,单元格会捕捉到整个屏幕。现在,我想在捕捉后执行一个方法。部分显示之前或之后。

以下是我为捕捉效果编写的代码:

func scrollToMostVisibleCell(){
    let visibleRect = CGRect(origin: collectionView.contentOffset, size: collectionView.bounds.size)
    let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
    let visibleIndexPath = collectionView.indexPathForItem(at: visiblePoint)!
    collectionView.scrollToItem(at: visibleIndexPath as IndexPath, at: .top, animated: true)
    print("cell is ---> ", visibleIndexPath.row)
}



func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    scrollToMostVisibleCell()
}

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    scrollToMostVisibleCell()
    if !decelerate {
        scrollToMostVisibleCell()
    }
}

如果我使用willDisplayCell方法,那么即使该单元格在collectionView中进行偷窥,它也会在视图中立即返回我。

有没有一种方法可以检查单元格是否完全在视图中,然后执行功能?

关于这个问题,我已经放弃了互联网,但是找不到满意的答案。

2 个答案:

答案 0 :(得分:1)

在对单元格执行任何操作之前,请使用followedCollectionView.indexPathsForVisibleItems()获取可见的单元格visibleIndexPaths,并检查您的indexPath是否包含在visibleIndexPaths中。 参考:@anhtu Check whether cell at indexPath is visible on screen UICollectionView

也来自Apple:var visibleCells: [UICollectionViewCell] { get }。返回当前由集合视图显示的可见单元格的数组。

答案 1 :(得分:0)

这是启用了页面调度(5个纯色单元)的“全屏”垂直滚动收集视图控制器的完整示例。当单元格“捕捉到适当位置”时,它将触发scrollViewDidEndDecelerating,您可以在其中获取当前单元格的索引并执行所需的任何操作。

在情节提要中添加新的UICollectionViewController,并将其类别分配给VerticalPagingCollectionViewController。无需在情节提要中更改控制器的任何默认设置-所有这些都在下面的代码中处理:

//
//  VerticalPagingCollectionViewController.swift
//
//  Created by Don Mag on 10/31/18.
//

import UIKit

private let reuseIdentifier = "Cell"

class VerticalPagingCollectionViewController: UICollectionViewController {

    private var collectionViewFlowLayout: UICollectionViewFlowLayout {
        return collectionViewLayout as! UICollectionViewFlowLayout
    }

    private var colors: [UIColor] = [.red, .green, .blue, .yellow, .orange]

    override func viewDidLoad() {
        super.viewDidLoad()

        // Register cell classes
        self.collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)

        // enable paging
        self.collectionView?.isPagingEnabled = true

        // set section insets and item spacing to Zero
        collectionViewFlowLayout.sectionInset = UIEdgeInsets.zero
        collectionViewFlowLayout.minimumLineSpacing = 0
        collectionViewFlowLayout.minimumInteritemSpacing = 0
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        if let cv = collectionViewLayout.collectionView {
            collectionViewFlowLayout.itemSize = cv.frame.size
        }
    }

    override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        if let iPath = collectionView?.indexPathsForVisibleItems.first {
            print("DidEndDecelerating - visible cell is: ", iPath)
            // do what you want here...
        }
    }

    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return colors.count
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
        cell.backgroundColor = colors[indexPath.item]
        return cell
    }

}