ASCollectionView
  • July 11, 2025

This repository is no longer maintained. Here’s why:


  • with the release of iOS 16 SwiftUI now enables most of the features this library was created to replace.
  • The UIHostingConfiguration API makes it easy to implement custom UICollectionViews using SwiftUI cells. This implementation handles cell-resizing and updates much better than a third party component is able to.
  • In cases where a collection view is overkill, the new SwiftUI Layout protocol is the better choice. We’ve started a small library of native layouts here

README:


A SwiftUI implementation of UICollectionView & UITableView. Here’s some of its useful features:

  • supports preloading and onAppear/onDisappear.
  • supports cell selection, with automatic support for SwiftUI editing mode.
  • supports autosizing of cells.
  • supports the new UICollectionViewCompositionalLayout, and any other UICollectionViewLayout
  • supports removing separators for ASTableView.
  • supports directly using FetchedResults as a data source

Pull requests and suggestions welcome 🙂

Report Bug · Suggest a feature

 

 

Getting Started


ASCollectionView is a swift package.

Alternatively, if you’re unable to use SPM for some reason, you can import it using cocoapods: pod 'ASCollectionView-SwiftUI', '~> 1.3'

Usage


Basic example – single section:

import ASCollectionView
import SwiftUI

struct SingleSectionExampleView: View
{
@State var dataExample = (0 ..< 30).map { $0 }

var body: some View
{
ASCollectionView(data: dataExample, dataID: \.self)
{ item, _ in
Color.blue
.overlay(Text(“\(item)”))
}
.layout
{
.grid(
layoutMode: .adaptive(withMinItemSize: 100),
itemSpacing: 5,
lineSpacing: 5,
itemSize: .absolute(50))
}
}
}

Multiple sections with unique data sources

Below is an example of how to include a collection view with two sections (each with their own data source). For an extended example with a custom compositional layout see here. Or for more in-depth examples download the demo project included in this repo.

import SwiftUI
import ASCollectionView

struct ExampleView: View
{
@State var dataExampleA = (0 ..< 21).map { $0 }
@State var dataExampleB = (0 ..< 15).map { “ITEM \($0)” }

var body: some View
{
ASCollectionView
{
ASCollectionViewSection(
id: 0,
data: dataExampleA,
dataID: \.self)
{ item, _ in
Color.blue
.overlay(
Text(“\(item)”)
)
}
ASCollectionViewSection(
id: 1,
data: dataExampleB,
dataID: \.self)
{ item, _ in
Color.green
.overlay(
Text(“Complex layout – \(item)”)
)
}
.sectionHeader
{
Text(“Section header”)
.padding()
.frame(maxWidth: .infinity, alignment: .leading) // Fill width and align text to the left
.background(Color.yellow)
}
.sectionFooter
{
Text(“This is a section footer!”)
.padding()
}
}
.layout
{ sectionID in
switch sectionID
{
case 0:
// Here we use one of the provided convenience layouts
return .grid(
layoutMode: .adaptive(withMinItemSize: 100),
itemSpacing: 5,
lineSpacing: 5,
itemSize: .absolute(50))
default:
return ASCollectionLayoutSection
{ environment in
// …
// You could return any custom NSCollectionLayoutSection here. For an example see this file: /readmeAssets/SampleUsage.swift
// …
}
}
}
}
}

Supplementary Views

ASCollectionView has support for supplementary views. To add a supplementary view, use the sectionHeadersectionFooter, or sectionSupplementary modifiers on your ASCollectionViewSection.

  • sectionHeader and sectionFooter set the supplementary for UICollectionView.elementKindSectionHeader and UICollectionView.elementKindSectionHeader respectively.
  • sectionSupplementary lets you specify any supplementaryKind.

ASCollectionViewSection(…) { … }
.sectionHeader
{
Text(“Section header”)
.background(Color.yellow)
}
.sectionFooter
{
Text(“Section footer”)
.background(Color.blue)
}
.sectionSupplementary(ofKind: “someOtherSupplementaryKindRequestedByYourLayout”)
{
Text(“Section supplementary”)
.background(Color.green)
}

Decoration Views

A UICollectionViewLayout can layout decoration views that do not relate to the data (eg. a section background). These cannot be configured so you must provide a View struct that can be initialised using .init().

  • To enforce this requirement, your view must conform to the Decoration protocol. The only requirement of this is an initialiser with no arguments.
  • You must register the view type with the layout.
  • See the Reminders screen of the Demo app for a working example.

Declaring a swift view conforming to Decoration:

struct GroupBackground: View, Decoration
{
let cornerRadius: CGFloat = 12
var body: some View
{
RoundedRectangle(cornerRadius: cornerRadius)
.fill(Color(.secondarySystemGroupedBackground))
}
}

Registering the decoration type with the layout (ASCollectionLayout):

var layout: ASCollectionLayout<Section>
{
ASCollectionLayout<Section>
{
// … Here is an example of including a decoration in a compositional layout.
let sectionBackgroundDecoration = NSCollectionLayoutDecorationItem.background(elementKind: “groupBackground”)
sectionBackgroundDecoration.contentInsets = section.contentInsets
section.decorationItems = [sectionBackgroundDecoration]
// …
}
.decorationView(GroupBackground.self, forDecorationViewOfKind: “groupBackground”) // REGISTER the decoration view type
}

Layout

  • There is inbuilt support for the new UICollectionViewCompositionalLayout.
    • You can define layout on a per-section basis, including the use of a switch statement if desired.
    • Work in progress: There are some useful methods that allow for easy definition of list and grid-based layouts (including orthogonal grids).

Define layout for all sections:

ASCollectionView(…) { … }
.layout
{
ASCollectionLayoutSection
{ layoutEnvironment in
// Construct and return a NSCollectionLayoutSection here
}
}

Define layout per section:

ASCollectionView(…) { … }
.layout
{ sectionID in
switch sectionID
{
case .userSection:
return ASCollectionLayoutSection
{ layoutEnvironment in
// Construct and return a NSCollectionLayoutSection here
}
}
case .postSection:
return ASCollectionLayoutSection
{ layoutEnvironment in
// Construct and return a NSCollectionLayoutSection here
}
}

Use a custom UICollectionViewLayout:

ASCollectionView(…) { … }
.layout
{
let someCustomLayout = CustomUICollectionViewLayout()
someCustomLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
return someCustomLayout
}

GitHub


View Github

YOU MIGHT ALSO LIKE...
ConfettiView

A SwiftUI View that emits confetti with user-defined shapes, images, and text.

SwiftUI Colour Wheel

A colour wheel made all in SwiftUI. There are 2 different colour wheels to choose from. The first main one ...

ColorPickerRing

A color picker implementation with color wheel appearance written in plain SwiftUI. It is compatible with UIColor and NSColor.