确定屏幕上水平 CollectionView 单元格的可见性百分比

Lan*_*ria 1 uiscrollview ios uicollectionview swift

我有一个水平集合视图。总会有 2 个并排的单元格,它们都有相同的宽度和高度。这些单元格播放视频,滚动时我想加载屏幕上 70% 的下一个单元格的视频,并停止小于该单元格的视频。我发现了几个类似的问题,但所有内容似乎都引用了 1 个单元格。

1- 单元格 59 和 60 均 100% 在屏幕上

在此输入图像描述

2-向左滚动,屏幕上59仍大于70%,60为100%,61小于30%

在此输入图像描述

3- 仍在向左滚动,59 小于屏幕上的 30%,60 为 100%,61 大于 70%

在此输入图像描述

任何内容都已经可见,如前两张照片中的单元格 59 和所有三张照片中的单元格 60 中的内容,我有逻辑阻止单元格再次加载,即使cell.loadNewVideo()将为它们运行。

layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    let width = UIScreen.main.bounds.width / 2
    return CGSize(width: width, height: 150)
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {

    collectionView.visibleCells.forEach { cell in
        guard let cell = cell as? VideoCell else { continue }

        guard let indexPath = collectionView.indexPath(for: cell) else { return }
        guard let layoutAttributes = collectionView.layoutAttributesForItem(at: indexPath) else { return }
        let cellFrameInSuperview = collectionView.convert(layoutAttributes.frame, to: collectionView.superview)
        guard let superView = collectionView.superview else { return }
        let convertedRect = collectionView.convert(cellFrameInSuperview, to: superView)
        let intersect = collectionView.frame.intersection(convertedRect)

        if intersect.width > (UIScreen.main.bounds.width / 2) * 0.7 {

            cell.loadNewVideo()

        } else {

            cell.destroyOldVideo()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我也尝试了相同的代码scrollViewWillEndDragging,但它也不起作用:

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {

}
Run Code Online (Sandbox Code Playgroud)

mat*_*att 11

这件事你想太多了。忘记layoutAttributes所有那些花哨的东西,只做你说你想做的事:找出屏幕上有多少单元格

单元格是一个视图。屏幕(比方说,由窗口表示)是一个视图。将它们相交!在适当转换的坐标中查看单元格框架与窗口(或其他内容)的交集,以获取屏幕上的单元格部分,并将其大小与单元格框架大小进行比较。这就是你的百分比。现在做任何你喜欢的百分比。

在这个例子中,“anything you like”只是显示百分比

在此输入图像描述

override func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let cells = self.collectionView.visibleCells
    for cell in cells {
        let f = cell.frame
        let w = self.view.window!
        let rect = w.convert(f, from: cell.superview!)
        let inter = rect.intersection(w.bounds)
        let ratio = (inter.width * inter.height) / (f.width * f.height)
        let rep = (String(Int(ratio * 100)) + "%")
        let label = cell.contentView.subviews.first as! UILabel
        label.text = rep
    }
}
Run Code Online (Sandbox Code Playgroud)