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:
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:
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.
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.
You are correct that calling setNeedsUpdateConfiguration() normally produces an asynchronous update. However, if you call it from inside an animation, like this:
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.
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.