【问题标题】:Determine Percentage of Visibility of Horizontal CollectionView Cells on Screen确定屏幕上水平 CollectionView 单元格的可见性百分比
【发布时间】:2021-09-07 12:02:47
【问题描述】:

我有一个水平的collectionView。总会有 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()
        }
    }
}

我也尝试了相同的代码scrollViewWillEndDragging,但它也没有用:

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

}

【问题讨论】:

  • 你知道使用 scrollViewDidScroll 有什么问题吗?
  • 它给出的结果不准确。例如,现在我从 59 滚动,现在 60 和 61 完全可见。我添加了打印语句,它说 59 不可见(销毁),但它也说 60 不可见,但 60 完全在屏幕上显示 61。它确实说 61 是可见的。有时当我从 61 滚动到 62 并且它们都在屏幕上完全可见时,它会说 61 可见但 62 不可见。
  • 那么一个问题是你为什么要查看布局属性?看看细胞在哪里。这毕竟是你想知道的。确定单元格是否在屏幕上的方法是将屏幕坐标中的单元格框架与屏幕边界进行比较。你问的是其他一些相当棘手的问题。
  • 我还能如何找出单元格的位置?从我读过的内容来看,这是找出细胞所在位置的方法。我怎样才能在不使用它的情况下细化可见单元格的百分比?
  • 将单元格框架的矩形转换为窗口内部坐标并将该矩形与窗口边界相交。将交叉点的面积与单元框的面积进行比较。那是你的百分比。保持简单。

标签: ios swift uicollectionview uiscrollview


【解决方案1】:

方式想太多了。忘掉layoutAttributes 和所有花哨的东西,做你说你想做的事:找出单元格有多少在屏幕上

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

在这个例子中,“任何你喜欢的”只是为了显示百分比。

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
    }
}

【讨论】:

  • 请注意,如果您正在做任何其他花哨的东西,例如变换,那将违反框架,因此在进行计算时请记住这一点。
  • 不错!我喜欢动画。我还没有机会尝试它,但我已经知道它有效。谢谢。 “花哨的东西”lmaoooooo,太真实了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多