Skip to content

engingulek/GenericCollectionViewKit

Repository files navigation

🧩 Generic Collection View Framework

A lightweight and reusable framework for UICollectionView written in Swift.
It provides a generic, type-safe, and highly customizable way to manage collection view data, section headers, delegates, and layouts. Compatible with Swift 5.9+ / iOS 14+.


✨ Features

  • ✅ Generic and reusable UICollectionViewDataSource
  • ✅ Generic and reusable UICollectionViewDelegate
  • ✅ Generic and reusable UICollectionViewCompositionalLayout
  • ✅ Clean protocol-oriented architecture
  • ✅ Supports dynamic section headers (titles + buttons)
  • ✅ Strongly typed, type-safe, and fully generic
  • ✅ Predefined layout templates for common scenarios
  • ✅ Minimal boilerplate with default implementations
Feature Description
🧩 Type Safety Strong typing everywhere ensures no AnyObject confusion
Reusable Write once, reuse across multiple collection views, headers, delegates, and layouts
🧼 Clean Architecture Separates data, layout, delegate, and UI logic
🧠 Extensible Easily extend with default methods, custom buttons, or layout templates

📜 CHeaderView

A customizable section header that supports a title ,optional action buttons and optional icon for title, making it easy to display section information dynamically.

  • A dynamic title (bold, resizable font)

  • Optiona left-aligned icon

  • Optional right-aligned buttons (e.g., “All List”, custom actions)

  • Auto-layout with UIStackView

  • Button tap callback closure

    HeaderIcon

Defines the icon displayed next to the title.

public enum TitleIconType { case systemImage(String) // SF Symbols case imageAsstes(String) // Asset Catalog images } public struct HeaderIcon { public let image: TitleIconType public let tintColor: HeaderItemColor }

HeaderViewItem

The main configuration model for CHeaderView.

public struct HeaderViewItem { public let title: String // Header title text public var icon: HeaderIcon? // Optional title icon public let sizeType: SectionSizeType // Header size / font style public var buttonTypes: [TitleForSectionButtonType] // Action buttons displayed on the right }

Configure

 header.configure(with: .init( title: item.title, icon: item.icon, sizeType: item.sizeType, buttonTypes: item.buttonTypes)) { [weak self] tappedType in guard let self else { return } source.onTappedTitleButton(buttonType: tappedType, section: indexPath.section) }

GenericCollectionDataSourceProtocol

A protocol-oriented, type-safe, and reusable approach for managing collection view data.
Defines a clean contract for UICollectionView data handling — sections, cells, and optional headers.

public protocol GenericCollectionDataSourceProtocol { associatedtype CellItem func numberOfSections() -> Int func numberOfRowsInSection(in section: Int) -> Int func cellForItem(section: Int, item: Int) -> CellItem func cellIdentifier(at section: Int) -> String func titleForSection(at section: Int) -> ( title: String, sizeType: SectionSizeType, buttonType: [TitleForSectionButtonType]? ) func onTappedTitleButton(buttonType: TitleForSectionButtonType, section: Int) }

Default Implementations

func titleForSection(at section: Int) -> HeaderViewItem func onTappedTitleButton(buttonType: TitleForSectionButtonType, section: Int) { } }

Supporting Types

SectionSizeType Controls the font size for section titles:

public enum SectionSizeType { case large, medium, small var size: CGFloat { ... } }

TitleForSectionButtonType Represents possible header button types:

public enum TitleForSectionButtonType { case allList case custom(String) var title: String { ... } }

Example Usage

struct MyModel { let name: String } final class MyCollectionDataSource: GenericCollectionDataSourceProtocol { typealias CellItem = MyModel func numberOfSections() -> Int { 2 } func numberOfRowsInSection(in section: Int) -> Int { 5 } func cellForItem(section: Int, item: Int) -> MyModel { MyModel(name: "Item \(item)") } func cellIdentifier(at section: Int) -> String { "MyCell" } func titleForSection(at section: Int) -> ( title: String, sizeType: SectionSizeType, buttonType: [TitleForSectionButtonType]? ) { (title: "Section \(section)", sizeType: .medium, buttonType: [.allList, .custom("Filter")]) } func onTappedTitleButton(buttonType: TitleForSectionButtonType, section: Int) { print("Tapped \(buttonType) in section \(section)") } }

Integration Example

let mySource = MyCollectionDataSource() let dataSource = GenericCollectionDataSource(source: mySource) { identifier, cell, item in guard let cell = cell as? MyCollectionViewCell, let model = item as? MyModel else { return } cell.configure(with: model) } collectionView.dataSource = dataSource

Generic Collection Delegate Source Protocol

A lightweight and reusable UICollectionView delegate written in Swift. It provides a generic, type-safe, and protocol-oriented way to handle item selection and scroll events in collection views.

public protocol GenericCollectionDelegateSourceProtocol { func didSelectItem(section: Int, item: Int) func scrollViewDidScroll(endOfPage: Bool) }

Default Implementations

public extension GenericCollectionDelegateSourceProtocol { func scrollViewDidScroll(endOfPage: Bool) { } func didSelectItem(section: Int, item: Int) { } }

Example Usage

final class MyDelegateSource: GenericCollectionDelegateSourceProtocol { func didSelectItem(section: Int, item: Int) { print("Selected item \(item) in section \(section)") } func scrollViewDidScroll(endOfPage: Bool) { if endOfPage { print("Reached end of page ✅") } } }

Integration Example

let source = MyDelegateSource() let delegate = GenericCollectionDelegate(source: source) collectionView.delegate = delegate

Generic Collection Layout Provider Protocol

A lightweight and reusable UICollectionViewCompositionalLayout framework written in Swift. Provides a generic, type-safe, and flexible way to configure collection view layouts.

public protocol GenericCollectionLayoutProviderProtocol { func layout(for sectionIndex: Int) -> LayoutSource }

LayoutSource

Describes the structure and behavior of the layout:

public struct LayoutSource { public init(groupOrientation: ScrollDirection, itemSize: SizeInfo, groupSize: SizeInfo, sectionInsets: (top: CGFloat, leading: CGFloat, bottom: CGFloat, trailing: CGFloat), interItemSpacing: CGFloat, interGroupSpacing: CGFloat, scrollDirection: ScrollDirection) { ... } }

Supporting Types

public enum DimensionType { case fractional, absolute, none } public struct SizeInfo { let width: (type: DimensionType, value: CGFloat) let height: (type: DimensionType, value: CGFloat) } public enum ScrollDirection { case horizontal, vertical }

Example Usage

final class MyLayoutSource: GenericCollectionLayoutProviderProtocol { func layout(for sectionIndex: Int) -> LayoutSource { switch sectionIndex { case 0: return LayoutSourceTeamplate.horizontalSingleRow.template case 1: return LayoutSourceTeamplate.verticalTwoPerRow.template default: return LayoutSourceTeamplate.none.template } } } let layoutProvider = GenericCollectionLayoutProvider(source: MyLayoutSource()) let layout = layoutProvider.createLayout() let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)

Tutorial Video

GenericCollectionViewKit.mov
GenericCollectionView.mov

🧰 Installation

dependencies: [ .package(url: "https://github.com/engingulek/GenericCollectionViewKit.git", from: "0.0.2") ]

About

A lightweight and reusable framework for UICollectionView written in Swift.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages