I'd like to add a gradient to a collection view cell's background in the context of the new collection view with compositional layouts. Here's an example of how a cell's background is configured from Apple's sample code Implementing Modern Collection Views in line 180 of EmojiExplorerViewController
:
func configuredGridCell() -> UICollectionView.CellRegistration<UICollectionViewCell, Emoji> {
return UICollectionView.CellRegistration<UICollectionViewCell, Emoji> { (cell, indexPath, emoji) in
var content = UIListContentConfiguration.cell()
content.text = emoji.text
content.textProperties.font = .boldSystemFont(ofSize: 38)
content.textProperties.alignment = .center
content.directionalLayoutMargins = .zero
cell.contentConfiguration = content
var background = UIBackgroundConfiguration.listPlainCell()
background.cornerRadius = 8
background.strokeColor = .systemGray3
background.strokeWidth = 1.0 / cell.traitCollection.displayScale
cell.backgroundConfiguration = background
}
}
Since the new UIBackgroundConfiguration
is a structure rather than a layer-backed UIView
subclass, I can't just add a CAGradientLayer
instance as a sublayer.
What would be a good approach to adding a gradient to a cell background configuration?
Yes, you can. The fact that UIBackgroundConfiguration is a struct is irrelevant. It has a
customView
property that's a view, and that will be used as the background view (behind the content view) in the cell. So set that view to something (it isnil
by default) and you're all set.Here's an example. This is a toy table view for test purposes, but the test is exactly about configuration objects, so it is readily adaptable to demonstrate the technique. It doesn't matter whether you're using a table view, a collection view, or neither, as long as you are using something that has a UIBackgroundConfiguration property. As you can see, I've made a vertical gradient from black to red as the background to my cells.
Here's the relevant code. First, I have defined a gradient-carrier view type:
Then, I use that view as the background view when I configure the cell:
Whatever else you want to achieve is merely a variant of the above. For example, you could use an image view or a solid background view and combine them with the gradient view. The point is, the
customView
is the background view, and whatever view you set it to will be displayed in the background of the cell.I should also point out that there is another way to do this, namely, to use a cell subclass and implement
updateConfigurationUsingState:
. The advantage of this approach is that once you've given the background configuration acustomView
, you can just modify thatcustomView
each time the method is called. You can use this technique to respond to selection, for example, as I have demonstrated in other answers here (such as https://stackoverflow.com/a/63064099/341994).