Skip to content

Recommended UIContentConfiguration / UIContentView pattern for table and collection cells #59

Description

@astralchen

Question

Related to #12, but this question is about UIKit’s configuration-based cell architecture rather than applying @QuickLayout directly to each cell subclass.

QuickLayout currently special-cases UITableViewCell and UICollectionViewCell so that a cell’s QuickLayout body is hosted in cell.contentView. With UIContentConfiguration, UIKit creates and manages a custom UIContentView. I could not find an example of this pattern and am unsure which object should own QuickLayout layout and sizing.

When a generic UITableViewCell or UICollectionViewCell receives a custom UIContentView, is applying @QuickLayout to that content view the supported approach?

Minimal example

struct CardConfiguration: UIContentConfiguration {
  let title: String

  @MainActor
  func makeContentView() -> any UIView & UIContentView {
    CardContentView(configuration: self)
  }

  func updated(for state: any UIConfigurationState) -> Self {
    self
  }
}

@QuickLayout
final class CardContentView: UIView, UIContentView {
  private let titleLabel = UILabel()
  private var model: CardConfiguration

  var configuration: any UIContentConfiguration {
    get { model }
    set {
      guard let configuration = newValue as? CardConfiguration else { return }
      model = configuration
      titleLabel.text = configuration.title
      setNeedsLayout()
    }
  }

  init(configuration: CardConfiguration) {
    model = configuration
    super.init(frame: .zero)
    self.configuration = configuration
  }

  @available(*, unavailable)
  required init?(coder: NSCoder) {
    fatalError()
  }

  var body: Layout {
    HStack {
      titleLabel
    }
    .padding(.horizontal, 16)
    .padding(.vertical, 8)
  }
}

// The same configuration is assigned to either cell type:
cell.contentConfiguration = CardConfiguration(title: title)

Could you clarify:

  • Should @QuickLayout live only on the custom UIContentView, leaving the cell generic, or should the cell also adopt @QuickLayout?
  • For self-sizing table rows and collection items with estimated dimensions, is the generated sizeThatFits(_:) on the content view sufficient, or is cell-level sizing customization still required as discussed in Avoid overriding preferredLayoutAttributesFitting in every auto-sizing UICollectionViewCell #12?
  • When applying a configuration that changes the content size, is setNeedsLayout() sufficient? Should invalidateIntrinsicContentSize(), a cell-level invalidation call, or a QuickLayout-specific helper be used?
  • On iOS 16+, should supports(_:) be implemented so UIKit can reuse the existing content view?
  • Are there any differences in the recommended pattern for UITableViewCell and UICollectionViewCell?

An official example covering both cell types would be very helpful. Thanks!

Environment

  • QuickLayout: main at 38020f2
  • Swift 6
  • iOS 15+

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions