UIListContentConfiguration text color during selection

Hi,

This is how I'm currently configuring an UICollectionView sidebar cell.

let rowRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, SidebarItem> {
    (cell, indexPath, item) in
    
    var contentConfiguration = UIListContentConfiguration.sidebarSubtitleCell()
    contentConfiguration.text = item.title
    contentConfiguration.secondaryText = item.subtitle
    contentConfiguration.image = item.image
    cell.contentConfiguration = contentConfiguration
}

In order to specify the selection background color of the cell I'm setting the backgroundConfiguration property. This work as expected:

let rowRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, SidebarItem> {
    (cell, indexPath, item) in
    
    var contentConfiguration = UIListContentConfiguration.sidebarSubtitleCell()
    contentConfiguration.text = item.title
    contentConfiguration.secondaryText = item.subtitle
    contentConfiguration.image = item.image
    cell.contentConfiguration = contentConfiguration
    
    var backgroundConfiguration = UIBackgroundConfiguration.listSidebarCell()
    backgroundConfiguration.backgroundColorTransformer = UIConfigurationColorTransformer { [weak cell] (color) in
        if let state = cell?.configurationState {
            if state.isSelected || state.isHighlighted {
                return UIColor(named: "Primary")!
            }
        }
        return .clear
    }
    cell.backgroundConfiguration = backgroundConfiguration
}

Now I also need to change the text color based on the cell selection. When the cell is selected the text should be white. I tried to set the colorTransformer of textProperties of contentConfiguration like so:

contentConfiguration.textProperties.colorTransformer = UIConfigurationColorTransformer { [weak cell] (color) in
    if let state = cell?.configurationState {
        if state.isSelected || state.isHighlighted {
            return .white
        }
    }
    return .black
}

Unfortunately the text color does not change after the cell has been selected.

What am I doing wrong? Can anyone help me?

Thank you

Accepted Reply

For iOS 14, I think you have to subclass UICollectionViewListCell and override updateConfiguration(using state: UICellConfigurationState). It should work for iOS 15 also.

let cellConfiguration = UICollectionView.CellRegistration<MyCell, String>....
    override func updateConfiguration(using state: UICellConfigurationState) {
        super.updateConfiguration(using: state)
        guard var cConfig = self.contentConfiguration?.updated(for: state) as? UIListContentConfiguration else { return }
        cConfig.textProperties.colorTransformer = UIConfigurationColorTransformer { color in
            state.isSelected || state.isHighlighted ? .white : .black
        }
        cConfig.secondaryTextProperties.colorTransformer = UIConfigurationColorTransformer { color in
            state.isSelected || state.isHighlighted ? .white : .black
        }
        self.contentConfiguration = cConfig

        guard var bConfig = self.backgroundConfiguration?.updated(for: state) else { return }
        bConfig.backgroundColorTransformer = UIConfigurationColorTransformer { color in
            state.isSelected || state.isHighlighted ? .systemPink : .systemGray5
        }
        self.backgroundConfiguration = bConfig
    }
}
  • Overriding updateConfiguration works perfectly! Thanks!

Add a Comment

Replies

Could you check the state values by adding some print:

contentConfiguration.textProperties.colorTransformer = UIConfigurationColorTransformer { [weak cell] (color) in
    print("State", cell?.configurationState)
    if let state = cell?.configurationState {
        if state.isSelected || state.isHighlighted {
            print("white")
            return .white
        }
    }
   print("black")
    return .black
}
  • I did that, and the color transformer block is called only when the cell is displayed, but not when the cell is selected. The backgroundColorTransformer, on the other hand, is also called when the cell is selected.

    Any idea why textProperties.colorTransformer is not called when the cell is selected?

Add a Comment
let cellConfigiuration = UICollectionView.CellRegistration<UICollectionViewListCell, String> { cell, indexPath, itemIdentifier in
        var contentConfiguration = UIListContentConfiguration.sidebarSubtitleCell()
        contentConfiguration.text = "Primary Text: \(itemIdentifier)"
        contentConfiguration.secondaryText = "Secondary Text"
        cell.contentConfiguration = contentConfiguration

        var backgroundConfiguration = UIBackgroundConfiguration.listSidebarCell()
        backgroundConfiguration.backgroundColor = .systemGray5
        cell.backgroundConfiguration = backgroundConfiguration

        cell.configurationUpdateHandler = { cell, state in
            guard var cConfig = cell.contentConfiguration?.updated(for: state) as? UIListContentConfiguration else { return }
            cConfig.textProperties.colorTransformer = UIConfigurationColorTransformer { color in
                state.isSelected || state.isHighlighted ? .white : .black
            }
            cConfig.secondaryTextProperties.colorTransformer = UIConfigurationColorTransformer { color in
                state.isSelected || state.isHighlighted ? .white : .black
            }
            cell.contentConfiguration = cConfig

            guard var bConfig = cell.backgroundConfiguration?.updated(for: state) else { return }
            bConfig.backgroundColorTransformer = UIConfigurationColorTransformer { color in
                state.isSelected || state.isHighlighted ? .systemMint : .systemGray5
            }
            cell.backgroundConfiguration = bConfig
        }
    }
  • Thank you! That’s work great, but unfortunately configurationUpdateHandler is only available on iOS 15. Any idea how this can be achieved also on iOS 14?

  • See answer below.

Add a Comment

For iOS 14, I think you have to subclass UICollectionViewListCell and override updateConfiguration(using state: UICellConfigurationState). It should work for iOS 15 also.

let cellConfiguration = UICollectionView.CellRegistration<MyCell, String>....
    override func updateConfiguration(using state: UICellConfigurationState) {
        super.updateConfiguration(using: state)
        guard var cConfig = self.contentConfiguration?.updated(for: state) as? UIListContentConfiguration else { return }
        cConfig.textProperties.colorTransformer = UIConfigurationColorTransformer { color in
            state.isSelected || state.isHighlighted ? .white : .black
        }
        cConfig.secondaryTextProperties.colorTransformer = UIConfigurationColorTransformer { color in
            state.isSelected || state.isHighlighted ? .white : .black
        }
        self.contentConfiguration = cConfig

        guard var bConfig = self.backgroundConfiguration?.updated(for: state) else { return }
        bConfig.backgroundColorTransformer = UIConfigurationColorTransformer { color in
            state.isSelected || state.isHighlighted ? .systemPink : .systemGray5
        }
        self.backgroundConfiguration = bConfig
    }
}
  • Overriding updateConfiguration works perfectly! Thanks!

Add a Comment