我有一个集合视图,其中单元格的大小恰好等于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
中进行偷窥,它也会在视图中立即返回我。
有没有一种方法可以检查单元格是否完全在视图中,然后执行功能?
关于这个问题,我已经放弃了互联网,但是找不到满意的答案。
答案 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
}
}