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
visibleCellsproperty ofUICollectionViewdoes 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
indexPathsForVisibleItemsproperty. This is not ordered either but it is simple enough to sort that array ofIndexPathvalues and then select the first one from the sorted result.Your
scrollViewDidScrollbecomes: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 callingreloadData()for every little scroll event.