确定屏幕上水平 CollectionView 单元格的可见性百分比
Determine Percentage of Visibility of Horizontal CollectionView Cells on Screen
我有一个水平的 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>) {
}
你想多了。忘记 layoutAttributes
和所有花哨的东西,只做你说的你想做的事:找出 单元格 有多少 在屏幕上.
单元格是一个视图。屏幕(比方说,由 window 表示)是一个视图。与他们相交!在适当转换的坐标中查看单元格框架与 window(或其他)的交集,以获取屏幕上的单元格部分,并将其大小与单元格框架的大小进行比较。那是你的百分比。现在做任何你喜欢的百分比。
在这个例子中,“任何你喜欢的”只是为了显示百分比。
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
}
}
我有一个水平的 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>) {
}
你想多了。忘记 layoutAttributes
和所有花哨的东西,只做你说的你想做的事:找出 单元格 有多少 在屏幕上.
单元格是一个视图。屏幕(比方说,由 window 表示)是一个视图。与他们相交!在适当转换的坐标中查看单元格框架与 window(或其他)的交集,以获取屏幕上的单元格部分,并将其大小与单元格框架的大小进行比较。那是你的百分比。现在做任何你喜欢的百分比。
在这个例子中,“任何你喜欢的”只是为了显示百分比。
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
}
}