0

I want to have a 3 second fade on UICollectionViewCells after they have been displayed or 8 seconds - like how periscope fades out messages in a livestream. Here's the relevant part of my code:

override func cellForItem(at index: Int) -> UICollectionViewCell {
    // ...

    // Get the time interval since the message was posted
    let timeInterval = 11 - Date().timeIntervalSince(message.timestamp)

    // If within the last 3 seconds, begin a fade.
    if timeInterval <= 3, timeInterval > 0 {
        cell.alpha = CGFloat(1 - 3/timeInterval)
        cell.fadeAlpha(to: 0, duration: timeInterval) { finished in
            if finished {
                self.delegate?.removeMessage(withSectionController: self)
            }
        }
    } else if timeInterval <= 0 {
        // If 11 secs or more have passed, remove.
        self.delegate?.removeMessage(...)
        cell.alpha = 0
    } else {
        // Otherwise start a timer
        timer = Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector: #selector(removeMessage), userInfo: nil, repeats: false)
    }
    return cell
}


@objc private func removeMessage() {
    timer.invalidate()
    // In other code I have got the cell
    // This is a UIView animation that changes the alpha
    cell.fadeAlpha(to: 0, duration: 3) { finished in
        if finished {
            self.delegate?.removeMessage(...)
        } else {
            // This gets cancelled on other cells when removeMessage gets called on a cell.
        }
    }
}


// In the delegate
func removeMessage(...) {
    model.messages.removeFirst()
    // This performs updates on the collection view data
    performUpdates()
}

... means there is other code but its not relevant.

My code works except when my collection view updates the cells, any current fades are cancelled. How can I fix this?

Tometoyou
  • 7,792
  • 12
  • 62
  • 108
  • Do not set the cell `alpha` if that cell is already in the middle of a fade. – matt Dec 01 '17 at 16:35
  • @matt I thought that if the cell was reloaded I would set the initial alpha of the cell and carry on the fade from there – Tometoyou Dec 01 '17 at 16:38

1 Answers1

0

You should implement this as a custom UICollectionViewLayout. After display set a timer to remove the message from your model, and delete the cell by calling

deleteItems(at: [IndexPath])

on your collection view for the item that you want to fade out.

In your custom layout you will want to have implemented

finalLayoutAttributesForDisappearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes?

and return a UICollectionViewLayoutAttributes instance with the alpha property set to 0.

This method specifies the attributes that will be animated to when removing an item from the collection view.

George Green
  • 4,807
  • 5
  • 31
  • 45
  • How can I set it to fade to alpha 0 over a 3 second period? – Tometoyou Dec 01 '17 at 19:02
  • Ah, I see. That's not actually easily available as far as I'm aware. Checkout this question https://stackoverflow.com/questions/12922780/how-do-you-set-the-duration-for-uicollectionview-animations for a few solutions that can achieve the custom duration. – George Green Dec 01 '17 at 19:32