@Frameworks Engineer Thank you for your reply.
I highly encourage you to read my updated question on stack overflow, as I suggested doing in a previous reply.
In particular, the question has been made explicit and is also now clearly introduced by a header.
Could you please answer the question by modifying the provided code?
Playing around with configurationUpdateHandler didn't do it for me.
Problem
If you tap on the row, it doesn't look like it gets selected: the line backgroundConfiguration.backgroundColor = .systemBlue breaks the cell's default background color transformer.
Question
Given that my goal is to have my cell manifest its selection exactly like usual (meaning exactly as it would without the line backgroundConfiguration.backgroundColor = .systemBlue), that the details of how a cell usually does so are likely not public, that I would like to set a custom background color for my cell and that I would want to configure its appearance using configurations, since I seem to understand that that is the way to go from iOS 14 onwards, does anybody know how to achieve my goal by resetting something to whatever it was before I said backgroundConfiguration.backgroundColor = .systemBlue?
What I've tried and didn't work:
Setting the collection view's delegate and specifying that you can select any row
Setting the color transformer to .grayscale
Setting the cell's backgroundConfiguration to UIBackgroundConfiguration.listGroupedCell().updated(for: cell.configurationState)
Setting the color transformer to cell.defaultBackgroundConfiguration().backgroundColorTransformer
Using collection view controllers (and setting collectionView.clearsSelectionOnViewWillAppear to false)
Setting the cell's automaticallyUpdatesBackgroundConfiguration to false and then back to true
Putting the cell's configuration code inside a configurationUpdateHandler
Combinations of the approaches above
Setting the color transformer to UIBackgroundConfiguration.listGroupedCell().backgroundColorTransformer and cell.backgroundConfiguration?.backgroundColorTransformer (they're both nil)
Workaround 1: use a custom color transformer
var backgroundConfiguration = UIBackgroundConfiguration.listGroupedCell()
backgroundConfiguration.backgroundColorTransformer = .init { _ in
if cell.configurationState.isSelected || cell.configurationState.isHighlighted || cell.configurationState.isFocused {
.systemRed
} else {
.systemBlue
}
}
cell.backgroundConfiguration = backgroundConfiguration
Workaround 2: don't use a background configuration
You can set the cell's selectedBackgroundView, like so:
let v = UIView()
v.backgroundColor = .systemBlue
cell.selectedBackgroundView = v
You won't be able to use custom background content configurations though and might want to use background views instead:
var contentConfiguration = UIListContentConfiguration.cell()
contentConfiguration.text = "Hello"
cell.contentConfiguration = contentConfiguration
let v = UIView()
v.backgroundColor = .systemBlue
cell.backgroundView = v
let bv = UIView()
bv.backgroundColor = .systemRed
cell.selectedBackgroundView = bv
Consideration on the workarounds
Both workarounds seem to also not break this code, which deselects cells on viewWillAppear(_:) and was taken and slightly adapted from Apple's Modern Collection Views project (e.g. EmojiExplorerViewController.swift):
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
deselectSelectedItems(animated: animated)
}
func deselectSelectedItems(animated: Bool) {
if let indexPath = collectionView.indexPathsForSelectedItems?.first {
if let coordinator = transitionCoordinator {
coordinator.animate(alongsideTransition: { [weak self] context in
self?.collectionView.deselectItem(at: indexPath, animated: true)
}) { [weak self] (context) in
if context.isCancelled {
self?.collectionView.selectItem(at: indexPath, animated: false, scrollPosition: [])
}
}
} else {
collectionView.deselectItem(at: indexPath, animated: animated)
}
}
}
(Collection view controllers don't sport all of that logic out of the box, even though their clearsSelectionOnViewWillAppear property is true by default.)