I am trying to implement a simple list with custom cells using an UICollectionView on iOS 14. My custom cell should display a title and a corresponding value in the following style.

But the actual result now looks something like this:

I started to utilise the new way of configuring cells using the UICellConfigurationState.
My solution consists of:
- A custom
UIContentConfiguration - A custom
UIContentView - A custom
UICollectionViewListCell
Now I have trouble to see how I can constrain my custom UIContentView to be aligned with the cells separator layout guide. My code looks as follows:
// MARK: - UIContentConfiguration
struct DisplayCellContentConfiguration: UIContentConfiguration, Hashable {
var title: String?
var value: String?
func makeContentView() -> UIView & UIContentView {
return DisplayCellContentView(configuration: self)
}
func updated(for state: UIConfigurationState) -> Self {
// Perform update on parameters that does not related to cell's data items
// Make sure we are dealing with instance of UICellConfigurationState
guard state is UICellConfigurationState else {
return self
}
// Update self based on the current state
let updatedConfiguration = self
return updatedConfiguration
}
}
// MARK: - Content View
class DisplayCellContentView: UIView, UIContentView {
// MARK: - UI Properties
private lazy var stackView = UIStackView().with {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.axis = .horizontal
$0.distribution = .equalSpacing
$0.isLayoutMarginsRelativeArrangement = true
}
private lazy var titleLabel = UILabel().with {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.textColor = .label
$0.font = UIFont.preferredFont(forTextStyle: .body)
$0.adjustsFontForContentSizeCategory = true
}
private lazy var valueLabel = UILabel().with {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.textColor = .secondaryLabel
$0.font = UIFont.preferredFont(forTextStyle: .body)
$0.adjustsFontForContentSizeCategory = true
}
// MARK: - UIContentView conforming
private var currentConfiguration: DisplayCellContentConfiguration!
var configuration: UIContentConfiguration {
get {
currentConfiguration
}
set {
// Make sure the given configuration is of type DisplaySettingsCellContentConfiguration
guard let newConfiguration = newValue as? DisplayCellContentConfiguration else {
return
}
// Apply the new configuration
// also update currentConfiguration to newConfiguration
apply(configuration: newConfiguration)
}
}
// MARK: - Initializers
init(configuration: DisplayCellContentConfiguration) {
super.init(frame: .zero)
// Create the content view UI
setupView()
// Apply the configuration (set data to UI elements / define custom content view appearance)
apply(configuration: configuration)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
// MARK: - Content View UI Setup
private extension DisplayCellContentView {
private func setupView() {
//TODO: I would expect leading to be 16 here, but this does not work on real devices. In the simulator 16 is correct, on real devices it is 20
addSubview(stackView)
NSLayoutConstraint.activate([
stackView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20),
stackView.topAnchor.constraint(equalTo: topAnchor, constant: 11),
stackView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -11),
stackView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -11)
])
stackView.addArrangedSubview(titleLabel)
stackView.addArrangedSubview(valueLabel)
}
private func apply(configuration: DisplayCellContentConfiguration) {
// Only apply configuration if new configuration and current configuration are not the same
guard currentConfiguration != configuration else {
return
}
// Replace current configuration with new configuration
currentConfiguration = configuration
// Set data to UI elements
titleLabel.text = configuration.title
valueLabel.text = configuration.value
}
}
// MARK: - UICollectionViewListCell
/// A UICollectionViewListCell that displays a title on the left and a corresponding value on the right side of the cell
class DisplayListCell: UICollectionViewListCell {
var item: DisplayValueCell?
override func updateConfiguration(using state: UICellConfigurationState) {
// Create new configuration object and update it base on state
var newConfiguration = DisplayCellContentConfiguration().updated(for: state)
// Update any configuration parameters related to data item
newConfiguration.title = item?.title
newConfiguration.value = item?.value
// Set content configuration in order to update custom content view
contentConfiguration = newConfiguration
}
}
The issue I see in this code is in DisplayCellContentView.setupView(). The layout constraint values here are rather guessed than really known and additionally only work on a real device but not in the simulator. So my question is, how can I consistently align my custom cell view with the separator layout guide leading anchor ?
Any help is appreciated !