Animations with cells configurations

I wonder how to make an animation on a view inside a cell visible on-screen based on iOS 14 cell configuration API.

Imagine I want to animate the visibility of a placeholder view, in the old style, I would have write something like this:


Code Block
class MyCell: UICollectionViewCell {
var placeholderVisible: Bool {
get {
return placeholderVisibleBackingValue
}
set {
setPlaceholderVisible(newValue, animated: false)
}
}
func setPlaceholderVisible(_ visible: Bool, animated: Bool) {
placeholderVisibleBackingValue = visible
updatePlaceHolderVisibility(animated: animated)
}
private func updatePlaceHolderVisibility(animated: Bool) {
if animated {
UIView.animate(withDuration: 0.5) {
placeholderView.alpha = placeholderVisible ? 1 : 0
}
} else {
placeholderView.alpha = placeholderVisible ? 1 : 0
}
}
}


WWDC 2020 "Modern Cell Configuration" session briefly mentions animations at 09:09 time. It says that we can nest a configuration change inside an animation block.

In practice, I'm not sure how I could do this because every configuration change needs to call setNeedsUpdateConfiguration(). Since it's an async method, nesting this method in an animation block would not work.

Here is a code snippet of a custom cell based on a cell configuration API:

Code Block
class MyCell: UICollectionViewListCell {
var placeholderVisible: Bool = false {
didSet {
guard oldValue != placeholderVisible else {
return
}
setNeedsUpdateConfiguration()
}
}
override var configurationState: UICellConfigurationState {
var state = super.configurationState
/* `state.placeholderVisible` is a custom key in the UICellConfigurationState key value store */
state.placeholderVisible = placeholderVisible
return state
}
override func updateConfiguration(using state: UICellConfigurationState) {
var content = defaultListContentConfiguration().updated(for: state)
listContentView.configuration = content
placeholderView.alpha = state.placeholderVisible ? 1 : 0
}
}


Apple recommendation is to always write all the cell’s configuration in a single place updateConfiguration(using state: UICellConfigurationState). Since this method is called by setNeedsUpdateConfiguration()which is async, I don't know how I could apply an animation when changing the alpha value of the placeholderView.
Answered by Frameworks Engineer in 627397022
You are correct that calling setNeedsUpdateConfiguration() normally produces an asynchronous update. However, if you call it from inside an animation, like this:

Code Block swift
UIView.animate(withDuration: 0.5) {
setNeedsUpdateConfiguration()
}


it will actually perform a synchronous update, so that any changes that occur as a result of updating the configuration are automatically animated.

With that said, the exact animations you will see depend on what is actually changed, and the type of animations that are supported. Background configurations have the most robust support for animations: if you set a new background configuration inside an animation, most properties are natively animatable, and for those that aren't like the customView, you'll get a cross-fade between the old and new one. List content configurations have more limited support for animations: while they will animate layout changes, changes to the actual content and other image or text properties will flip between the old & new values at the halfway point of the animation, as those properties aren't natively animatable.

Please submit feedback if you'd like to see more built-in support for animations, such as the ability to cross-fade between images/text with a list content configuration.
Accepted Answer
You are correct that calling setNeedsUpdateConfiguration() normally produces an asynchronous update. However, if you call it from inside an animation, like this:

Code Block swift
UIView.animate(withDuration: 0.5) {
setNeedsUpdateConfiguration()
}


it will actually perform a synchronous update, so that any changes that occur as a result of updating the configuration are automatically animated.

With that said, the exact animations you will see depend on what is actually changed, and the type of animations that are supported. Background configurations have the most robust support for animations: if you set a new background configuration inside an animation, most properties are natively animatable, and for those that aren't like the customView, you'll get a cross-fade between the old and new one. List content configurations have more limited support for animations: while they will animate layout changes, changes to the actual content and other image or text properties will flip between the old & new values at the halfway point of the animation, as those properties aren't natively animatable.

Please submit feedback if you'd like to see more built-in support for animations, such as the ability to cross-fade between images/text with a list content configuration.
Thank you for that detailed answer.

I had naively tried to perform an animation with setNeedsUpdateConfiguration() in an animation block but it didn't work. Now that I know that it's a correct pattern handled by UIKit, I will make other tests.
Animations with cells configurations
 
 
Q