Search code examples
iosuitableviewios14

How does a UIConfigurationColorTransformer work?


Apple says:

Because color transformers can use the same base input color to produce a number of variants of that color, you can create different appearances for different states of your views.

Okay. I would like to try using the new iOS 14 backgroundConfiguration architecture instead of setting the cell's backgroundView and selectedBackgroundView. I want my UITableViewCell to have a blue background normally but a gray background when selected. So, in my cellForRowAt implementation:

var b = UIBackgroundConfiguration.listPlainCell()
b.backgroundColor = .blue
cell.backgroundConfiguration = b

So far, so good; the cell is blue. But what about the gray? This is where I expect the color transformer to come in:

var b = UIBackgroundConfiguration.listPlainCell()
b.backgroundColor = .blue
b.backgroundColorTransformer = // what?
cell.backgroundConfiguration = b

The color transformer is a function that takes a color and returns a color. And I can see by logging that the color transformer function is actually called every time the cell's state changed. But the function itself doesn't take a state. It has no access to the cell's state. So how do I, as Apple claims, "create different appearances for different states"?


Solution

  • As near as I can tell, there are two parts to the answer:

    • You are configuring the background configuration in cellForRowAt, so you have a reference to the cell and therefore to its cell configuration state.

    • If you set the background configuration's backgroundColor explicitly, you can't set it through the backgroundColorTransformer. It's one or the other. (That feels buggy to me, but whatever.)

    So, the following does what I want:

    var b = UIBackgroundConfiguration.listPlainCell()
    b.backgroundColorTransformer = UIConfigurationColorTransformer { [weak cell] c in
        if let state = cell?.configurationState {
            if state.isSelected || state.isHighlighted {
                return .gray
            }
        }
        return .blue
    }
    cell.backgroundConfiguration = b