[英]With collectionView.isPagingEnabled = true how to know when paging is completed
I have a vertical direction cell that is the same size of the collectionView and I set collectionView.isPagingEnabled = true
.我有一个与 collectionView 大小相同的垂直方向单元格,并且我设置了
collectionView.isPagingEnabled = true
。 There is only 1 active visible cell on screen at a time:屏幕上一次只有 1 个活动的可见单元格:
layout.scrollDirection = .vertical
collectionView.isPagingEnabled = true
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
// collectionView is the same width and height as the device
let width = collectionView.frame.width
let height = collectionView.frame.height
return CGSize(width: width, height: height)
}
I need to know when the entire cell is on screen after the user swipes either up and down (when the page is finished paging and centered on screen).我需要知道用户上下滑动后整个单元格何时出现在屏幕上(当页面完成分页并在屏幕上居中时)。 Or in other words I need to know when the user isn't swiping or dragging in between cells.
或者换句话说,我需要知道用户何时不在单元格之间滑动或拖动。 I tried this:
我试过这个:
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if decelerate {
if scrollView.frame.height == collectionView.frame.height {
let indexPaths = collectionView.indexPathsForVisibleItems
for indexPath in indexPaths {
if let cell = collectionView.cellForItem(at: indexPath) as? MyCell {
print("currentCell: \(indexPath.item)") // do something in cell
}
}
}
}
}
The problem I ran into is even if I drag 1/2 way, meaning if I'm on item 2, drag 1/2 to item 3, then drag back to item 2, the print("currentCell: \(indexPath.item)")
will print out currentCell: 3
then currentCell: 2
.我遇到的问题是即使我拖动 1/2 方式,这意味着如果我在第 2 项上,将 1/2 拖动到第 3 项,然后拖回第 2 项,即
print("currentCell: \(indexPath.item)")
将打印出currentCell: 3
然后currentCell: 2
。 The only time it should print currentCell: 3
is if that cell is completely on screen and not in between cell 2 and 3 (or 2 and 1 etc).它应该打印
currentCell: 3
的唯一时间是该单元格完全在屏幕上,而不是在单元格 2 和 3(或 2 和 1 等)之间。
You can try something like this:你可以尝试这样的事情:
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
let y = targetContentOffset.pointee.y
let item = Int(y / view.frame.height)
print("current cell: \(item)")
}
In this code I am using frame's width to divide x as my collectionView was horizontal, you can use height for vertical axis.在这段代码中,我使用框架的宽度来划分 x,因为我的 collectionView 是水平的,您可以使用高度作为垂直轴。 Hope it helps
希望能帮助到你
you could use:你可以使用:
var currentCellIndexPath: IndexPath? = nil {
didSet {
guard oldValue != currentCellIndexPath else { return }
// Get the cell
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let ratio = scrollView.contentOffset.y / scrollView.contentSize.height
let candidate = ratio.rounded()
guard abs(candidate - ratio) < 0.1 else { return }
guard collectionView.indexPathsForVisibleItems.count > 1 else {
guard !collectionView.indexPathsForVisibleItems.isEmpty else {
return
}
currentCellIndexPath = collectionView.indexPathsForVisibleItems[0]
}
let firstIdx = collectionView.indexPathsForVisibleItems[0]
let secondIdx = collectionView.indexPathsForVisibleItems[1]
if candidate > ratio {
currentCellIndexPath = secondIdx > firstIdx ? secondIdx : firstIdx
} else {
currentCellIndexPath = secondIdx > firstIdx ? firstIdx : secondIdx
}
}
Another solution, for your case, you have maximum 2 index paths in collectionView.indexPathsForVisibleItems.另一种解决方案,对于您的情况,您在 collectionView.indexPathsForVisibleItems 中最多有 2 个索引路径。
so all you need is check what is correct one if there're two index paths.因此,如果有两个索引路径,您只需要检查一个正确的。 you can check by:
您可以通过以下方式检查:
let ratio = scrollView.contentOffset.y / scrollView.contentSize.height
let isUpper = ratio - CGFloat(Int(ratio)) > 0.5
then if isUpper = true, it's the second indexPath in array.然后如果 isUpper = true,它是数组中的第二个 indexPath。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.