What Is SectionKit? A Swift Framework for Data-Driven Collection Views

SectionKit is a Swift framework that abstracts UICollectionView into reusable, composable sections, eliminating monolithic data sources through a mediator-based architecture that enables declarative, type-safe list construction.

SectionKit, housed in the linhay/sectionkit repository, reimagines iOS collection view development by isolating UI concerns into self-contained "sections" rather than cramming logic into massive view controllers. Each section encapsulates its own model binding, cell registration, layout logic, and interaction handling, while a central manager coordinates everything behind the scenes.

Core Architecture of SectionKit

The framework rests on a protocol-oriented design that prioritizes composition over inheritance, allowing developers to build heterogeneous lists by combining independent sections.

The Mediator Pattern: SKCManager

At the heart of SectionKit sits SKCManager, a mediator that installs itself as the UICollectionView delegate and data source. Rather than forwarding events to a monolithic controller, SKCManager routes each delegate call to the appropriate section based on the global index path. This implementation in Sources/SectionKit/CollectionBase/SKCManager.swift handles dataSourceForward, flowLayoutForward, and prefetchForward calls, ensuring sections remain unaware of their position in the larger collection.

Section Protocol Hierarchy

Sections conform to a strict protocol hierarchy defined in Sources/SectionKit/CollectionBaseProtocol/SKCSectionProtocol.swift: SKCSectionProtocol → SKCAnySectionProtocol → SKCRawSectionProtocol. This type-erasure strategy allows SKCManager to store a heterogeneous array of sections while maintaining compile-time safety. The protocols define the contract for data source methods, layout configurations, action handling, and lifecycle callbacks.

Concrete Implementation: SKCSingleTypeSection

For the common use case of homogeneous data arrays, SKCSingleTypeSection in Sources/SectionKit/CollectionSingleTypeSection/Entities/SKCSingleTypeSection.swift provides a generic, chainable API. Generic over Cell: UICollectionViewCell & SKConfigurableView & SKLoadViewProtocol, this class offers fluent methods like onCellAction(_:_:), setHeader(_:model:), and cellSafeSize that eliminate boilerplate while preserving type safety.

SectionUI: The Presentation Layer

SectionUI provides the visual integration layer, wrapping raw sections into usable interface components. Located under Sources/SectionUI, this layer includes SKWrapperCell and SKCWrapperReusableView helpers, plus ready-made subclasses like SKCollectionViewController that expose the manager via a manager property.

Composable Layout Plugins

Instead of subclassing UICollectionViewFlowLayout, SectionKit uses a plugin-based architecture found in Sources/SectionUI/CollectionView/SectionCollectionView/FlowLayout/SKCLayoutPlugins.swift. These composable objects attach to the manager to provide sticky headers, section backgrounds, alignment adjustments, and waterfall layouts. You mix and match behaviors—such as pinning headers with specific padding or adding decorative views—without touching layout delegate methods.

Building a SectionKit Interface: Practical Examples

Defining a Configurable Cell

Cells implement SKLoadViewProtocol (for automatic registration) and SKConfigurableView (for model binding):

class ItemCell: UICollectionViewCell,
                SKLoadViewProtocol,
                SKConfigurableView {
    struct Model {
        let title: String
        let subtitle: String
    }

    static func preferredSize(limit size: CGSize, model: Model?) -> CGSize {
        CGSize(width: size.width, height: 60)
    }

    func config(_ model: Model) {
        textLabel.text = model.title
        detailLabel.text = model.subtitle
    }

    private lazy var textLabel = UILabel()
    private lazy var detailLabel = UILabel()
}

Binding Data and Handling Interactions

In a SKCollectionViewController subclass, you configure sections using a fluent API:

class MyViewController: SKCollectionViewController {

    private lazy var section = ItemCell.wrapperToSingleTypeSection()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Configure actions
        section.onCellAction(.selected) { [weak self] context in
            print("Selected: \(context.model.title)")
        }

        // Provide models
        section.config(models: [
            .init(title: "Item 1", subtitle: "First"),
            .init(title: "Item 2", subtitle: "Second")
        ])

        // Display via the manager
        manager.reload(section)
    }
}

Adding Headers and Layout Plugins

Method chaining extends section capabilities without subclassing:

section
    .setHeader(MyHeaderView.self, model: "Section Title")
    .setDecoration(BackgroundView.self) { ctx in
        ctx.view.backgroundColor = .systemGroupedBackground
        ctx.view.layer.cornerRadius = 12
    }
    .pinHeader { opts in
        opts.padding = 16
    }

Reactive Programming with Combine

SectionKit integrates with Combine for automatic updates:

class ViewModel {
    @SKPublished var items: [ItemCell.Model] = []
}

let viewModel = ViewModel()
section.subscribe(models: viewModel.$items.eraseToAnyPublisher())

The @SKPublished property wrapper emits publishers that the section observes, triggering diff-based reloads automatically.

Summary

  • SectionKit abstracts UICollectionView into independent, reusable sections managed by SKCManager.
  • The mediator pattern in SKCManager.swift eliminates massive view controllers by routing delegate calls to specific sections.
  • Type-safe protocols (SKCSectionProtocol hierarchy) allow heterogeneous collections while maintaining compile-time checking.
  • SKCSingleTypeSection provides a generic, chainable API for the common single-cell-type use case.
  • SectionUI offers ready-made view controllers and a plugin-based layout system for sticky headers, decorations, and complex grids without subclassing UICollectionViewFlowLayout.
  • Combine integration enables reactive data binding with automatic diff-based animations.

Frequently Asked Questions

What is the difference between SectionKit and SectionUI?

SectionKit contains the core framework logic—the SKCManager mediator, section protocols, and SKCSingleTypeSection implementation—while SectionUI provides the visual layer including SKCollectionViewController, wrapper views, and layout plugins. You can use SectionKit's data architecture independently, but SectionUI simplifies integrating it into view controllers.

How does SectionKit handle heterogeneous collection views?

SectionKit manages heterogeneity through type erasure. While each SKCSingleTypeSection is generic over a specific cell type, they all conform to SKCSectionProtocol, allowing SKCManager to store them in a homogeneous array. The manager calculates global index paths and routes delegate methods to the correct section instance automatically.

What layout features does SectionKit support beyond standard flow layout?

Through the plugin system in SKCLayoutPlugins.swift, SectionKit supports sticky section headers with customizable pinning insets, decoration views for backgrounds and borders, alignment plugins for grid layouts, and waterfall-style arrangements. These compose together without subclassing UICollectionViewFlowLayout, allowing you to mix layout behaviors across different sections.

Can SectionKit improve collection view performance?

Yes. SectionKit includes SKHighPerformanceStore for caching cell sizes and reducing layout calculations, plus automatic diff-based reloading that computes minimal update sets. The prefetchForward system in SKCManager coordinates data prefetching across sections, ensuring smooth scrolling even with complex, heterogeneous content.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →