Search code examples
swiftuicollectionviewuicollectionviewcell

Cell loaded in cellForItemAt, but not in visibleCells


I have a custom UICollectionView and the cells are loaded in cellForItemAt but when I try to get all the visible cells by using visibleCells I'm not getting all the cells.

For example, in cellForItemAt, I'm setting the alpha of the labels in the cells to 0. When panned, I want the alpha of those labels change to 1:

func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
    handleLabel(scrollView, active: true)
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    if pickerIsActive { handleLabel(scrollView, active: false) }
}

private func handleLabel(_ scrollView: UIScrollView, active: Bool) {
    guard let pickerView = scrollView as? UICollectionView else { return }

    let cells = pickerView.visibleCells.flatMap { $0 as? CustomCell }

    panningIsActive = active

    UIView.animate(duration: 0.3) {
        cells.forEach { $0.label.alpha = $0.isSelected || active ? 1 : 0 }
    }
}

And cellForItemAt:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell

    cell.label.alpha = 0

    return cell
}

What can I do to change all the "loaded" cells instead of just the "visible" cells?


Solution

  • The visibleCells are only the on screen cells. This used to be everything initialized in cellForItem:at: but as of iOS 10 UICollectionView now prefetches to improve scrolling performance (see WWD 2016 video) which maybe why you are having this problem. Anyways it sounds like all you want to do is animate the cells to fade in when they come on screen. You can either move your animation logic to willDisplayCell or subclass UICollectionViewCell. UIColectionViewCell inherits from UIView, so you can override didMoveToSuperView in your UICollectionViewCell and call your animation method there, which will cause the cell to animate as it appears.