检查 indexPath 处的单元格在屏幕 UICollectionView 上是否可见
Check whether cell at indexPath is visible on screen UICollectionView
我有一个 CollectionView
可以向用户显示图像。我在后台下载这些,下载完成后我调用以下函数来更新 collectionViewCell
并显示图像。
func handlePhotoDownloadCompletion(notification : NSNotification) {
let userInfo:Dictionary<String,String!> = notification.userInfo as! Dictionary<String,String!>
let id = userInfo["id"]
let index = users_cities.indexOf({[=10=].id == id})
if index != nil {
let indexPath = NSIndexPath(forRow: index!, inSection: 0)
let cell = followedCollectionView.cellForItemAtIndexPath(indexPath) as! FeaturedCitiesCollectionViewCell
if (users_cities[index!].image != nil) {
cell.backgroundImageView.image = users_cities[index!].image!
}
}
}
如果单元格当前在屏幕上可见,这会很好用,但如果不是,我会得到一个
fatal error: unexpectedly found nil while unwrapping an Optional value
以下行出错:
let cell = followedCollectionView.cellForItemAtIndexPath(indexPath) as! FeaturedCitiesCollectionViewCell
现在,如果 collectionViewCell 尚不可见,甚至不需要调用此函数,因为在这种情况下,图像将在 cellForItemAtIndexPath
方法中设置。
因此我的问题是,如何更改此函数以检查我们正在处理的单元格当前是否可见。我知道 collectionView.visibleCells()
但是,我不确定如何在此处应用它。
获取当前可用单元格
// get visible cells
let visibleIndexPaths = followedCollectionView.indexPathsForVisibleItems
然后在对单元格进行任何操作之前检查 indexPath
是否包含在 visibleIndexPaths
数组中。
您可以简单地使用 if collectionView.cellForItem(at: indexPath) == nil { }
。 collectionView 只会 return 一个可见的单元格。
或者根据您的情况具体更改:
let cell = followedCollectionView.cellForItemAtIndexPath(indexPath) as! FeaturedCitiesCollectionViewCell
至:
if let cell = followedCollectionView.cellForItemAtIndexPath(indexPath) as? FeaturedCitiesCollectionViewCell { }
嵌套的 UICollectionViews 通常需要完全不滚动,因此不会提供任何 contentOffset,因此 iOS 将所有单元格理解为始终可见。那样的话可以参考屏幕边界:
let cellRect = cell.contentView.convert(cell.contentView.bounds, to: UIScreen.main.coordinateSpace)
if UIScreen.main.bounds.intersects(cellRect) {
print("cell is visible")
}
您可以通过
获取当前索引
// Called before the cell is displayed
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
print(indexPath.row)
}
// Called when the cell is displayed
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
print(indexPath.row)
}
我需要追踪可见的细胞,所以您也可以做类似的事情来更好地追踪您的细胞。
private func configureVisibleIndexPath() {
let visibleCells = collectionView.indexPathsForVisibleItems
visibleCells.forEach { indexPath in
if let cell = collectionView.cellForItem(at: indexPath), collectionView.bounds.contains(cell.frame) {
print("visible row is \(indexPath.row)"
}
}
}
当您的集合视图配置正确时调用此函数,它还通过在 scrollView 委托中调用它来关注滚动:
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if !decelerate {
configureVisibleIndexPath()
}
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
configureVisibleIndexPath()
}
是的,我尝试了很多方法,发现这是最好的。
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
const currentIndex = (indexPath.row + 1) % (total cell number)
}
您可以通过以下方式管理可见单元格。
https://github.com/NohEunTae/VisibilityTrackableCollectionView
只需设置检测边界即可:
collectionView.setBoundary(.init(view: someView, mode: .safeArea))
我有一个 CollectionView
可以向用户显示图像。我在后台下载这些,下载完成后我调用以下函数来更新 collectionViewCell
并显示图像。
func handlePhotoDownloadCompletion(notification : NSNotification) {
let userInfo:Dictionary<String,String!> = notification.userInfo as! Dictionary<String,String!>
let id = userInfo["id"]
let index = users_cities.indexOf({[=10=].id == id})
if index != nil {
let indexPath = NSIndexPath(forRow: index!, inSection: 0)
let cell = followedCollectionView.cellForItemAtIndexPath(indexPath) as! FeaturedCitiesCollectionViewCell
if (users_cities[index!].image != nil) {
cell.backgroundImageView.image = users_cities[index!].image!
}
}
}
如果单元格当前在屏幕上可见,这会很好用,但如果不是,我会得到一个
fatal error: unexpectedly found nil while unwrapping an Optional value
以下行出错:
let cell = followedCollectionView.cellForItemAtIndexPath(indexPath) as! FeaturedCitiesCollectionViewCell
现在,如果 collectionViewCell 尚不可见,甚至不需要调用此函数,因为在这种情况下,图像将在 cellForItemAtIndexPath
方法中设置。
因此我的问题是,如何更改此函数以检查我们正在处理的单元格当前是否可见。我知道 collectionView.visibleCells()
但是,我不确定如何在此处应用它。
获取当前可用单元格
// get visible cells
let visibleIndexPaths = followedCollectionView.indexPathsForVisibleItems
然后在对单元格进行任何操作之前检查 indexPath
是否包含在 visibleIndexPaths
数组中。
您可以简单地使用 if collectionView.cellForItem(at: indexPath) == nil { }
。 collectionView 只会 return 一个可见的单元格。
或者根据您的情况具体更改:
let cell = followedCollectionView.cellForItemAtIndexPath(indexPath) as! FeaturedCitiesCollectionViewCell
至:
if let cell = followedCollectionView.cellForItemAtIndexPath(indexPath) as? FeaturedCitiesCollectionViewCell { }
嵌套的 UICollectionViews 通常需要完全不滚动,因此不会提供任何 contentOffset,因此 iOS 将所有单元格理解为始终可见。那样的话可以参考屏幕边界:
let cellRect = cell.contentView.convert(cell.contentView.bounds, to: UIScreen.main.coordinateSpace)
if UIScreen.main.bounds.intersects(cellRect) {
print("cell is visible")
}
您可以通过
获取当前索引// Called before the cell is displayed
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
print(indexPath.row)
}
// Called when the cell is displayed
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
print(indexPath.row)
}
我需要追踪可见的细胞,所以您也可以做类似的事情来更好地追踪您的细胞。
private func configureVisibleIndexPath() {
let visibleCells = collectionView.indexPathsForVisibleItems
visibleCells.forEach { indexPath in
if let cell = collectionView.cellForItem(at: indexPath), collectionView.bounds.contains(cell.frame) {
print("visible row is \(indexPath.row)"
}
}
}
当您的集合视图配置正确时调用此函数,它还通过在 scrollView 委托中调用它来关注滚动:
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if !decelerate {
configureVisibleIndexPath()
}
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
configureVisibleIndexPath()
}
是的,我尝试了很多方法,发现这是最好的。
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
const currentIndex = (indexPath.row + 1) % (total cell number)
}
您可以通过以下方式管理可见单元格。
https://github.com/NohEunTae/VisibilityTrackableCollectionView
只需设置检测边界即可:
collectionView.setBoundary(.init(view: someView, mode: .safeArea))