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

> Learn to implement a custom section in SectionKit by creating a Swift class conforming to SKCSectionProtocol. This guide covers essential properties, cell registration, and item configuration for seamless integration.

- Repository: [神奇/sectionkit](https://github.com/linhay/sectionkit)
- Tags: how-to-guide
- Published: 2026-03-06

---

**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)](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/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:

```swift
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.

```swift
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)](https://github.com/linhay/sectionkit/blob/main/Sources/SectionKit/CollectionSingleTypeSection/Entities/SKCSingleTypeSection.swift), which handles registration and dequeuing automatically.

```swift
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`](https://github.com/linhay/sectionkit/blob/main/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`](https://github.com/linhay/sectionkit/blob/main/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.