Hash htk
Hash htk

Reputation: 71

How change the Selection Color in Compositional Layouts in CollectionView

I've recently worked with Compositional Layouts with Diffable DataSource. I've implemented side bar using UICollectionLayoutListConfiguration(appearance: .sidebar). I want to change the collection cell selection color to a custom color. I've used following code.

let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, MenuData> { (cell, indexPath, item) in            
    let red = UIView()
    red.backgroundColor = UIColor.red
    cell.selectedBackgroundView = red
    var content = cell.defaultContentConfiguration()
    content.text = item.menuTitle
    content.image = item.image
    cell.contentConfiguration = content           
}

though it applys the selection color, default cell configuration got override. is there any other approch to change the selection color

Upvotes: 7

Views: 3490

Answers (4)

BootMaker
BootMaker

Reputation: 1647

I played quite a lot with various solutions from the net, but Matt's answer works the best, as usual :).

Just for all of us - I mean simple minded programmers - I attach a complete solution for custom UITableViewCell with image using colour change for selection and highlight. It works.

Final screenshot:

Final screenshot

    class OwnerTableViewCell: UITableViewCell {

    var owner:OwnerElement!

    override func updateConfiguration(using state: UICellConfigurationState) {
        super.updateConfiguration(using: state)

        //Cell Content configuration
        var contentConfig = defaultContentConfiguration().updated(for: state)
        contentConfig.text = owner.ownerLastName
        contentConfig.secondaryText = owner.ownerEmail
        contentConfig.image = UIImage(systemName: "bell")

        //Cell Background configuration
        var backgroundConfig = UIBackgroundConfiguration.listPlainCell().updated(for: state)
        let backgroundImage = UIImageView(image: UIImage(named:"Cell_background_image"))
        backgroundImage.contentMode = .scaleToFill

        if state.isHighlighted || state.isSelected {
            let cellView = UIView()
            backgroundImage.addSubview(cellView)
            cellView.frame = backgroundImage.bounds
            cellView.backgroundColor = UIColor(red: (0.0/255.0), green: (0.0/255.0), blue: (255.0/255.0), alpha: 0.2)
            cellView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            
        }
        
        backgroundConfig.customView = backgroundImage

        contentConfiguration = contentConfig
        backgroundConfiguration = backgroundConfig

        }
    
}

Upvotes: 0

Phantom59
Phantom59

Reputation: 1119

If you're already subclassing a cell then updateConfiguration(using:) is definitely the way to go. But it seemed a bit excessive to have to subclass just to change the background color based on the state. There's a way to do it right in the cell's registration using the configuration's backgroundColorTransformer property. Here's how:

  var background = UIBackgroundConfiguration.listSidebarCell()
  background.backgroundColorTransformer = UIConfigurationColorTransformer { [weak cell] c in
    guard let state = cell?.configurationState else { return .clear }
    return state.isSelected || state.isHighlighted ? .gray : .clear
  }
  cell.backgroundConfiguration = background

This will set the cell's background to gray if selected or highlighted and clear otherwise. Credit goes to this article.

Upvotes: 10

Codi
Codi

Reputation: 11

You can use tintColor in Xcode 12/Swift 5 to change the color background of the selected cell when using Compositional Layouts with Diffable DataSources:

let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, MenuData> { (cell, indexPath, item) in
           
        cell.tintColor = .red
        
        var content = cell.defaultContentConfiguration()

        [...]
        
    }

Upvotes: 0

matt
matt

Reputation: 535850

You have to use a cell subclass that updates its own background on a state change. Example:

class MyCell : UICollectionViewCell {
    override func updateConfiguration(using state: UICellConfigurationState) {
        var back = UIBackgroundConfiguration.listPlainCell().updated(for: state)
        let v = UIView()
        if state.isSelected || state.isHighlighted {
            let v2 = UIView()
            v2.backgroundColor = UIColor.blue.withAlphaComponent(0.2)
            v.addSubview(v2)
            v2.frame = v.bounds
            v2.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        }
        back.customView = v
       
        self.backgroundConfiguration = back
    }
}

Upvotes: 4

Related Questions