Think of
UICellConfigurationState as a collection of all the inputs that affect how you would configure your cell. In other words, the properties on
UICellConfigurationState represent "what it is" (things like whether it is disabled or selected, traits such as the idiom and content size category, etc) — these are all properties of the cell and its environment at any point in time. Note that this doesn't include anything about "how it looks" (the exact styling or rendering being used) — that's what a background or content configuration is, and you generate one of those configurations for a specific
UICellConfigurationState.
So
UICellConfigurationState isn't just for interaction states (highlighted, selected, focused, reordering, etc). UIKit provides those properties because those are common generally-applicable states, and the default system-provided configurations return appearance customizations for many of those states.
You can use custom states to add any additional data you want to
UICellConfigurationState. These can be simple boolean states specific to your app, e.g. a task manager app might have
isCompleted and
isOverdue properties for each task cell. However, if you use a view model to set up your cell (e.g. a struct that contains the formatted text, images, and other properties relevant to what the cell displays), that view model is an important direct input into the configuration of your cell, and it makes sense to incorporate that into the configuration state. (Note that while a lightweight view model tailored specifically to the needs of the cell would make sense, you almost certainly don't want to add an entire lower-level data layer model object as a custom state. As a best practice, views should never own or depend on your data layer model objects directly; generate a lightweight view model from your model object based on what you actually need to display.)
Ultimately the decision of what you use
UICellConfigurationState for is up to you. Here are some of the benefits of using it to encapsulate all of the data and inputs that you use to build your configurations:
Anytime any of the inputs change that might affect the configuration of the cell, you just need to call
setNeedsUpdateConfiguration(), and if there are multiple changes they will get coalesced into a single update automatically for best performance.
The code that builds your content and background configurations can be written as a pure function of the
UICellConfigurationState, meaning it does not rely on any other inputs and does not produce any side effects. For example, you could write a static function like this, which takes a
UICellConfigurationState and returns a pair of background & content configurations:
Code Block swift| static func configurations(for state: UICellConfigurationState) -> (UIBackgroundConfiguration, UIContentConfiguration) |
This pattern makes your code simpler to reason about, easier to debug, and makes it testable by default. It also makes it much easier to refactor and share in more places, as your implementation no longer depends on the cell class it gets used with, or any specific instance at all.
UICellConfigurationState can serve as a "common currency" that can be passed and shared across multiple parts of your code as needed. For example, your app might have custom states that are shared by many different cell classes, and then have a single shared styling component that can return colors (or entire configurations!) for different
UICellConfigurationState values passed to it from inside each cell class' implementation of
updateConfiguration(using state:).
Finally, if you create your own custom content configurations using the
UIContentConfiguration protocol, custom states allow your configuration to support automatic updates and return an updated version of itself for new states from
updated(for:) (documentation). This allows your custom content configuration to change its appearance based on your custom states, without having to write any code in your cell subclass to manually set properties on the configuration.
To answer your specific questions about the checkmark view properties:
checkmarkChecked
checkmarkTintColor
This may or may not make sense to model as a custom state. Usually, colors aren't an input into the cell configuration, they are an output based on the configuration state. If you'd change this color based on whether the cell is selected or not, for example, it probably doesn't belong in the configuration state itself, and if you were implementing a custom content configuration, this would be a property on that configuration instead. However, if you think of this color as a property of the cell or the item that the cell represents (e.g. perhaps it is a user-configurable color for that item, like how you can choose to assign a color to a file or folder in Finder on the Mac), then that color may make sense as part of your view model and/or UICellConfigurationState.