Disabling selection for individual list cells

While converting some table views into collection view lists, I have run into an issue with managing which cells are expected to show a highlighted or selected background when being tapped.

In this specific case, the list has a mix of cells where some have a traditional selection appearance and other should not show selection at all, but they should still be able to react to cell selection.

The only workaround I have found is to override func collectionView(_ collectionView: UICollectionView, shouldHighlightItemAt indexPath: IndexPath) -> Bool.

Is there a way to do this instead on the cell level?
Accepted Answer
First of all, it's important to distinguish the state of the item/cell (e.g. whether it is highlighted, whether it is selected) from the appearance of the cell (the visual result that you actually see). You won't see a different appearance without the state changing, but you can have cells that change state without changing their appearance. Depending on what you are trying to do, you might want to prevent both the state and appearance, or just prevent the appearance only.

If you don't want items to become highlighted or selected (i.e. you want to prevent both the state and appearance), returning false from the collectionView(_:shouldHighlightItemAt:) delegate method is the best way to do that. You can conditionally return true for some items and not others if you want.

If you only want to prevent the highlighted or selected appearance for a cell, but still want the corresponding item to be highlighted or selected, there are a few different ways you can do that. If your cell is using a background configuration (the default as of iOS 14), the simplest approach is to manually update the cell's background configuration yourself with a UICellConfigurationState that has the highlighted and/or selected states removed from it. Here is an example of how to do that in your cell subclass:

Code Block swift
override func updateConfiguration(using state: UICellConfigurationState) {
    automaticallyUpdatesBackgroundConfiguration = false
    
    var modifiedState = state
    modifiedState.isHighlighted = false
    modifiedState.isSelected = false
    backgroundConfiguration = backgroundConfiguration?.updated(for: modifiedState)
}


Note that if you're using a content configuration, you probably want to update it manually yourself as well, as some of the system content configuration styles also have variations for the highlighted and selected states.
Disabling selection for individual list cells
 
 
Q