# Can SectionKit Be Used with UICollectionViewFlowLayout? A Complete Guide

> Learn how to use SectionKit with UICollectionViewFlowLayout. Discover dependency injection and essential tips for native flow-layout pinning. Explore the linhay/sectionkit repository now.

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

---

**Yes, SectionKit fully supports UICollectionViewFlowLayout through dependency injection into SKCollectionView, though you must disable SectionKit's pin plugins when using native flow-layout pinning to prevent debug assertions.**

SectionKit is a powerful wrapper framework that simplifies building complex collection views in iOS. While it defaults to a custom `SKCollectionFlowLayout`, the architecture is layout-agnostic, allowing you to use SectionKit with UICollectionViewFlowLayout or any custom layout subclass while retaining all data-source and section-management features.

## How SectionKit Handles Layouts

The framework separates layout concerns from data management through the **SKCManager** orchestrator, making it compatible with any `UICollectionViewLayout` implementation.

### The Default SKCollectionFlowLayout

When you initialize `SKCollectionView` without parameters, it automatically creates an internal `SKCollectionFlowLayout` instance. According to the source in [`SKCollectionView.swift`](https://github.com/linhay/sectionkit/blob/main/SKCollectionView.swift) (lines 37-41), the default initializer constructs this custom layout to enable advanced plugin features like decorations and alignment:

```swift
// Default initialization uses SKCollectionFlowLayout
private let collectionView = SKCollectionView()  // Uses SKCollectionFlowLayout internally

```

This default layout powers the full plugin system but is not required for core SectionKit functionality.

### Injecting Custom UICollectionViewFlowLayout

You can inject any `UICollectionViewLayout` subclass by using the frame-based initializer. As implemented in [`SKCollectionView.swift`](https://github.com/linhay/sectionkit/blob/main/SKCollectionView.swift) (lines 42-46), the `init(frame:collectionViewLayout:)` method accepts custom layouts while still wiring up the SectionKit manager:

```swift
let flowLayout = UICollectionViewFlowLayout()
let collectionView = SKCollectionView(
    frame: .zero, 
    collectionViewLayout: flowLayout  // Inject custom layout
)

```

The **SKCManager** continues to handle section data, cell configuration, and compatible plugins regardless of the underlying layout class.

## Code Examples: Using SectionKit with UICollectionViewFlowLayout

### Default Configuration

To use SectionKit with its default setup, simply instantiate `SKCollectionView`. This uses the internal `SKCollectionFlowLayout` and enables all plugin features:

```swift
import SectionUI

class DemoViewController: UIViewController {
    private let collectionView = SKCollectionView()  // Default SKCollectionFlowLayout

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(collectionView)
        
        // Configure constraints...
        
        // Reload with SectionKit sections
        collectionView.manager.reload([
            makeSampleSection()
        ])
    }
}

```

### Injecting a Plain Flow Layout

To use a vanilla `UICollectionViewFlowLayout`, pass it through the designated initializer. This preserves all SectionKit data-source features while using standard UIKit layout logic:

```swift
import SectionUI

class PlainFlowViewController: UIViewController {
    private let flowLayout: UICollectionViewFlowLayout = {
        let layout = UICollectionViewFlowLayout()
        layout.minimumLineSpacing = 10
        layout.minimumInteritemSpacing = 10
        return layout
    }()
    
    private lazy var collectionView = SKCollectionView(
        frame: .zero,
        collectionViewLayout: flowLayout
    )

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(collectionView)
        
        // SKCManager still powers sections and cells
        collectionView.manager.reload([makeCustomSection()])
    }
}

```

### Handling Pinning Conflicts

When using native flow-layout pinning (`sectionHeadersPinToVisibleBounds`), you must disable SectionKit's pin plugins. The `Plugin+Pin.swift` file (lines 27-31) contains a debug assertion that triggers if both mechanisms are active:

```swift
class PinnedHeaderViewController: UIViewController {
    private let collectionView = SKCollectionView()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(collectionView)
        
        // Enable native UIKit pinning
        collectionView.collectionViewFlowLayout?.sectionHeadersPinToVisibleBounds = true
        
        // Explicitly disable SectionKit pin plugins to avoid assertionFailure
        collectionView.set(pluginModes: [
            .verticalAlignment([]),
            // Do NOT include .pinHeader or .pinFooter
        ])
        
        collectionView.manager.reload([makePinnedSection()])
    }
}

```

If you inadvertently enable both, the debug build will crash with the message: *"SKCSectionPinOptions is not compatible with UICollectionViewFlowLayout's pinning feature."*

## Architecture Deep Dive

Understanding the source files helps clarify why SectionKit works with any layout.

### SKCollectionView.swift

Located at [`Sources/SectionUI/CollectionView/SectionCollectionView/SKCollectionView.swift`](https://github.com/linhay/sectionkit/blob/main/Sources/SectionUI/CollectionView/SectionCollectionView/SKCollectionView.swift), this class bridges SectionKit to UIKit. It owns an **SKCManager** instance that manages sections and cells independent of layout calculations. The file exposes two critical initialization paths:

- **Default initializer**: Creates `SKCollectionFlowLayout` (lines 37-41)
- **Custom layout initializer**: Accepts any `UICollectionViewLayout` (lines 42-46)

Both paths register the manager's request publishers, ensuring section updates work regardless of layout type.

### Plugin+Pin.swift Assertions

The file `Sources/SectionUI/Sections/Plugin+Pin.swift` implements sticky headers and footers through SectionKit's plugin system. Lines 27-31 contain a compatibility guard:

```swift
#if DEBUG
if let layout = sectionView.collectionViewLayout as? UICollectionViewFlowLayout,
   layout.sectionHeadersPinToVisibleBounds == true || 
   layout.sectionFootersPinToVisibleBounds == true {
    assertionFailure("SKCSectionPinOptions is not compatible with UICollectionViewFlowLayout's pinning feature...")
}
#endif

```

This prevents undefined behavior when both SectionKit plugins and native UIKit pinning attempt to control header/footer positioning.

## Summary

- **SectionKit supports UICollectionViewFlowLayout** through the `init(frame:collectionViewLayout:)` initializer in [`SKCollectionView.swift`](https://github.com/linhay/sectionkit/blob/main/SKCollectionView.swift).
- **SKCManager** handles all data-source and section logic independently of layout calculations, ensuring full feature compatibility.
- **Layout plugins** like pinning require `SKCollectionFlowLayout`; disable them when using native `UICollectionViewFlowLayout` pinning to avoid debug assertions in `Plugin+Pin.swift`.
- **Example implementations** in [`Example/Layouts/TestCollectionViewFlowLayout.swift`](https://github.com/linhay/sectionkit/blob/main/Example/Layouts/TestCollectionViewFlowLayout.swift) demonstrate production-ready custom flow layouts with SectionKit.

## Frequently Asked Questions

### Can I use SectionKit's pin plugins with UICollectionViewFlowLayout?

No, SectionKit's pin plugins are incompatible with native `UICollectionViewFlowLayout` pinning. You must choose one mechanism. If you enable `sectionHeadersPinToVisibleBounds` on your flow layout, do not include `.pinHeader` or `.pinFooter` in your `pluginModes` array.

### What happens if I enable both native pinning and SectionKit pin plugins?

The framework triggers an `assertionFailure` in debug builds at `Plugin+Pin.swift` (lines 27-31). This guard prevents runtime conflicts where both systems attempt to calculate sticky header positions. Release builds will not crash, but layout behavior becomes undefined.

### Do I lose SectionKit features when using a custom flow layout?

You retain all core features including section abstraction, cell reuse, and data-source management through **SKCManager**. You only lose access to layout-specific plugins that depend on `SKCollectionFlowLayout`, such as advanced decoration views or SectionKit's proprietary pinning system.

### How do I initialize SKCollectionView with a custom layout?

Use the designated initializer that accepts a layout parameter: `SKCollectionView(frame:collectionViewLayout:)`. This injects your custom `UICollectionViewFlowLayout` while still initializing the internal manager and delegate-forwarding system required for SectionKit functionality.