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

Answered by anils in 700964022

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
    }
}

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
}
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
        }
    }
Accepted Answer

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
    }
}
UIListContentConfiguration text color during selection
 
 
Q