MH175
MH175

Reputation: 2334

How do I get UIConfigurationState without a reference to the cell?

Normally, when updating a cell's contentConfiguration for a particular cell's state you ask the cell for its contentConfiguration, then update it using updated(for:).

let content = cell.defaultContentConfiguration().updated(for: cell.configurationState)

However, in order to get this state you first need to have a reference to the cell. UIConfigurationState doesn't have an initializer. How can get the updated styling for a state without a reference to the cell?

For example, here I am trying to create a reusable configuration that adjusts itself for particular state

class Person {
    let name: String
}

extension Person {

    func listContentConfig(state: UICellConfigurationState) -> UIListContentConfiguration {
        var content = UIListContentConfiguration.cell().updated(for: state)
        content.text = self.name
        return content
    }

}

Then, during cell registration I can configure it with my reusable config.

extension UICollectionViewController {
    
    func personCellRegistration(person: Person) -> UICollectionView.CellRegistration<UICollectionViewListCell, Person> {
        return .init { cell, indexPath, person in
            cell.contentConfiguration = person.listContentConfig(state: cell.configurationState)
        }
    }
    
}

That works fine, but what if I want to mix and match different properties for difference states? In order to actually get this state I need to first get the cell, update the state, then set it back. This is quite a few steps.

extension UICollectionViewController {
    
    func personCellRegistration(person: Person) -> UICollectionView.CellRegistration<UICollectionViewListCell, Person> {
        return .init { cell, indexPath, person in
            // 1. Change the cell's state
            cell.isUserInteractionEnabled = false
            // 2. Grab my content config for the new state
            let disabledConfig = person.listContentConfig(state: cell.configurationState)
            // 3. Change the cell's state back
            cell.isUserInteractionEnabled = true
            // 4. Get the cell's default config
            var defaultConfig = cell.defaultContentConfiguration()
            // 5. Copy the pieces I want
            defaultConfig.textProperties.color = disabledConfig.textProperties.color
        }
    }
    
}

What I'd like is to be able to do something like this:

extension Person {

    func listContentConfig(state: UICellConfigurationState) -> UIListContentConfiguration {
        let disabledState = UICellConfigurationState.disabled // no such property exists.
        var content = UIListContentConfiguration.cell().updated(for: disabledState)
        // customize...
    }
}

I realize that I could pass in the cell itself to my reusable config, but this a) breaks encapsulation, b) defeats the purpose of configurations to be view agnostic, c) requires the same number of steps.

(FYI: The reason I am doing this is to allow the user to delete a cell that represents 'missing data'. The cell's style should appear disabled, but when setting isUserInteractionEnabled = false the delete accessory becomes unresponsive.)

Am I missing something?

Upvotes: 0

Views: 812

Answers (0)

Related Questions