我有一个垂直的 UICollectionView,当我滚动时,我希望第一个单元格比其他单元格稍大。
这段代码部分解决了我的问题...... 但是,当我滚动到列表末尾时,最后一个单元格而不是第一个单元格会增加。
var firstVisibleCell = 0
extension someCollectionView: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let visibleCells = visibleCells
if let firstCell = visibleCells.first {
if let indexPath = indexPath(for: firstCell)?.row {
firstVisibleCell = indexPath
print(indexPath)
}
}
reloadData()
}
}
extension someCollectionView: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if indexPath.row == firstVisibleCell {
return CGSize(width: self.bounds.width * 0.9, height: 120)
}
return CGSize(width: self.bounds.width * 0.85, height: 120)
}
}
在调试过程中,我看到一旦滚动到末尾,值就会从序数变化...例如 0..1..2..3..7
这可能是因为最后一个单元格变得可见。 滚动时如何只增加列表中的第一个单元格?
visibleCells
的UICollectionView
属性并未说明单元格数组是按任何顺序排列的。您假设数组中的第一个单元格是最顶部可见的单元格。
我会使用
indexPathsForVisibleItems
属性。这也不是有序的,但它很简单,可以对 IndexPath
值的数组进行排序,然后从排序结果中选择第一个。
你的
scrollViewDidScroll
变成:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if let indexPath = indexPathsForVisibleItems.sorted().first {
firstVisibleCell = indexPath
print(indexPath)
}
reloadData()
}
作为旁注,我会避免调用
reloadData()
。当用户滚动时,它会被多次调用。只重新加载顶部单元格并且仅在顶部单元格更改时重新加载可能会好得多。您还需要重新加载之前的顶部单元格。仅在需要时重新加载这两个单元格,将比为每个小滚动事件调用 reloadData()
更有效。