I have a vertical UICollectionView and when I scroll I want the first cell to be slightly larger than the others.
This code partially solves my problem... However, when I scroll to the end of the list, the last cell is incremented instead of the first one.
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)
}
}
During debugging, I see that as soon as I scroll to the end, the value changes from ordinal... For example 0..1..2..3..7
This is probably because the last cell becomes visible. How can I make only the first cell in the list increase when scrolling?
The visibleCells
property of UICollectionView
does not state that the array of cells is in any kind of order. You are assuming the first cell in the array is top-most visible cell.
I would use the indexPathsForVisibleItems
property. This is not ordered either but it is simple enough to sort that array of IndexPath
values and then select the first one from the sorted result.
Your scrollViewDidScroll
becomes:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if let indexPath = indexPathsForVisibleItems.sorted().first {
firstVisibleCell = indexPath
print(indexPath)
}
reloadData()
}
As a side comment, I'd avoid calling reloadData()
. That will get called many times as the user scrolls. It would probably be a lot better to reload just the top cell and only when the top cell changes. You will also need to reload the previous top cell as well. Reloading just those two cells, and only when needed, will be far more efficient than calling reloadData()
for every little scroll event.