How to Implement a Custom Section in SectionKit: Complete Protocol Guide

To implement a custom section in SectionKit, create a Swift class conforming to SKCSectionProtocol, implement the required properties sectionInjection, safeSizeProvider, and itemCount, register your cell classes in config(sectionView:), and handle cell dequeuing and configuration in item(at:).

SectionKit by linhay provides a protocol-oriented architecture for managing UICollectionView sections as independent, reusable components. When the built-in SKCSingleTypeSection is insufficient for heterogeneous cells or custom layout logic, you must implement a custom section by conforming to the framework's core protocols. The source code in [Sources/SectionKit/CollectionBaseProtocol/SKCSectionProtocol.swift](https://github.com/linhay/sectionkit/blob/main/Sources/SectionKit/CollectionBaseProtocol/SKCSectionProtocol.swift) defines the contract your implementation must satisfy.

Understanding the Core Protocols

SectionKit treats every logical block of a collection view as a section. The protocol hierarchy consists of:

  • SKCBaseSectionProtocol – Bundles data-source, delegate, and action handling capabilities.
  • SKCSectionProtocol – Extends the base protocol to add UICollectionViewDelegateFlowLayout support and SKCAnySectionProtocol conformance.

For most custom implementations, conform directly to SKCSectionProtocol. This protocol provides default implementations for many helper methods through extensions in SKCDataSourceProtocol, allowing you to override only the specific behaviors you need to customize.

Required Components for a Custom Section

Every custom section must provide specific properties and methods that the SKCManager uses to render content:

  • sectionInjection – A variable of type SKCSectionInjection? that the manager sets automatically to provide context about the section's position and collection view.
  • safeSizeProvider – A lazy-initialized SKSafeSizeProvider that supplies size constraints for preferredSize calculations. Initialize using defaultSafeSizeProvider for standard behavior.
  • itemCount – An integer property returning the number of rows in the section.
  • config(sectionView:) – A method where you register all cell classes and supplementary views with the collection view using the register() helper.
  • item(at:) – A method that dequeues and configures the UICollectionViewCell for a specific row using dequeue(at:).

Optional but commonly implemented methods include itemSize(at:) for returning specific sizes per row, and item(selected:) for handling user interactions.

Step-by-Step Implementation Guide

Follow these steps to create a robust custom section capable of handling heterogeneous cell types:

  1. Create a new Swift file and declare a class conforming to SKCSectionProtocol and SKSafeSizeProviderProtocol.
  2. Define a data structure (such as an enum) representing the different cell types your section will display.
  3. Implement required properties: sectionInjection, safeSizeProvider, and itemCount.
  4. Register cells in config(sectionView:) for every cell type used in the section.
  5. Configure cells in item(at:) by switching on your data structure, dequeuing the appropriate cell type, and applying its model.
  6. Provide sizes in itemSize(at:) if you need per-cell sizing, or rely on the default implementation if your cells use SKLoadViewProtocol.

Complete Heterogeneous Section Example

The repository provides a reference template in [Sources/.agent/skills/sectionui/examples/MixedCellsSectionTemplate.swift](https://github.com/linhay/sectionkit/blob/main/.agent/skills/sectionui/examples/MixedCellsSectionTemplate.swift) demonstrating a section mixing multiple cell types. Below is the implementation pattern:

import SectionUI
import UIKit

final class MyMixedSection: SKCSectionProtocol, SKSafeSizeProviderProtocol {
    enum CellType {
        case header(HeaderCell.Model)
        case item(ItemCell.Model)
        case footer(FooterCell.Model)
    }
    
    var sectionInjection: SKCSectionInjection?
    lazy var safeSizeProvider: SKSafeSizeProvider = defaultSafeSizeProvider
    private var cellTypes: [CellType] = []
    
    var itemCount: Int { cellTypes.count }
    
    init(cellTypes: [CellType] = []) {
        self.cellTypes = cellTypes
    }
    
    func config(sectionView: UICollectionView) {
        register(HeaderCell.self)
        register(ItemCell.self)
        register(FooterCell.self)
    }
    
    func itemSize(at row: Int) -> CGSize {
        switch cellTypes[row] {
        case .header(let model):
            return HeaderCell.preferredSize(limit: safeSizeProvider.size, model: model)
        case .item(let model):
            return ItemCell.preferredSize(limit: safeSizeProvider.size, model: model)
        case .footer(let model):
            return FooterCell.preferredSize(limit: safeSizeProvider.size, model: model)
        }
    }
    
    func item(at row: Int) -> UICollectionViewCell {
        switch cellTypes[row] {
        case .header(let model):
            let cell = dequeue(at: row) as HeaderCell
            cell.config(model)
            return cell
        case .item(let model):
            let cell = dequeue(at: row) as ItemCell
            cell.config(model)
            return cell
        case .footer(let model):
            let cell = dequeue(at: row) as FooterCell
            cell.config(model)
            return cell
        }
    }
    
    func item(selected row: Int) {
        guard case .item(let model) = cellTypes[row] else { return }
        print("Item tapped: \(model.title)")
    }
}

Integrating with SKCManager

Once implemented, add your custom section to a collection view via SKCManager. The manager automatically calls config(sectionView:) upon insertion and forwards all data-source and delegate callbacks to your section instance.

import SectionKit

let header = HeaderCell.Model(title: "Welcome")
let items = (1...10).map { ItemCell.Model(title: "Item \($0)", subtitle: nil) }
let footer = FooterCell.Model(text: "End of list")

let cellTypes: [MyMixedSection.CellType] = [
    .header(header),
    .item(items[0]),
    .footer(footer)
]

let mixedSection = MyMixedSection(cellTypes: cellTypes)
let manager = SKCManager(collectionView: collectionView)
manager.append(section: mixedSection)

When to Use SKCSingleTypeSection Instead

If your section uses only one cell type, skip the custom implementation. Use SKCSingleTypeSection defined in [Sources/SectionKit/CollectionSingleTypeSection/Entities/SKCSingleTypeSection.swift](https://github.com/linhay/sectionkit/blob/main/Sources/SectionKit/CollectionSingleTypeSection/Entities/SKCSingleTypeSection.swift), which handles registration and dequeuing automatically.

import SectionKit

let models = ["A", "B", "C"]
let singleSection = SKCSingleTypeSection<MyCell>(models)
manager.append(section: singleSection)

Summary

  • Conform to SKCSectionProtocol to create custom sections with full control over heterogeneous cells and layout.
  • Implement required properties including sectionInjection, safeSizeProvider, and itemCount to satisfy the protocol contract.
  • Register cells in config(sectionView:) to ensure the collection view can dequeue reusable cells.
  • Dequeue and configure in item(at:) using the dequeue(at:) helper method provided by the protocol extensions.
  • Use SKCSingleTypeSection for homogeneous cell types to avoid boilerplate code.
  • Reference the template in Sources/.agent/skills/sectionui/examples/MixedCellsSectionTemplate.swift for production-ready patterns.

Frequently Asked Questions

What is the difference between SKCBaseSectionProtocol and SKCSectionProtocol?

SKCBaseSectionProtocol provides the foundational data-source and delegate method signatures required for any section implementation. SKCSectionProtocol extends this base protocol to add UICollectionViewDelegateFlowLayout support and SKCAnySectionProtocol conformance, making it the preferred choice for flow layout-based collection views according to the source in Sources/SectionKit/CollectionBaseProtocol/SKCSectionProtocol.swift.

How does SKCManager communicate with my custom section?

SKCManager maintains a reference to your section through the sectionInjection property, which the manager sets automatically when you append the section using manager.append(section:). This injection provides the section with its context, including the collection view instance, enabling methods like dequeue(at:) and register() to function without manual view management.

Can I skip implementing itemSize(at:) in my custom section?

Yes. While implementing itemSize(at:) allows you to return specific sizes per row, SectionKit provides a default implementation. If your cells conform to SKLoadViewProtocol or you use fixed sizes, the default behavior may suffice. However, for heterogeneous sections with varying cell dimensions or dynamic content, explicit implementation is recommended for accurate layout calculations.

Where should I register supplementary views like headers and footers?

Register supplementary views within the config(sectionView:) method alongside your cell registrations. The protocol extension provides register() methods for both cells and supplementary views. The manager calls config(sectionView:) once when the section is first added to the collection view, ensuring all reusable identifiers are established before any dequeuing occurs.

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 →