Skip to content

chiahsien/CHTCollectionViewWaterfallLayout

Repository files navigation

CHTCollectionViewWaterfallLayout

Swift Package Manager compatible CocoaPods compatible Platform Build Status

CHTCollectionViewWaterfallLayout is a subclass of UICollectionViewLayout, and it tries to imitate UICollectionViewFlowLayout's usage as much as possible.

This layout is inspired by Pinterest.

Screenshots

2 columns

Features

  • Easy to use, it tries to imitate UICollectionViewFlowLayout's usage as much as possible.
  • Highly customizable.
  • Outstanding performance, try 10,000+ items and see the smoothness for yourself.
  • Support header and footer views.
  • Different column counts in different sections.

Buy Me A Coffee

Requirements

  • iOS 13+ / tvOS 13+
  • Swift 5.0+ or Objective-C

How to Install

Swift Package Manager (Recommended)

Add it to the dependencies value of your Package.swift:

dependencies: [
  .package(url: "https://github.com/chiahsien/CHTCollectionViewWaterfallLayout.git", from: "1.0.0")
]

Two library products are available:

  • CHTCollectionViewWaterfallLayout — Swift implementation
  • CHTCollectionViewWaterfallLayoutObjC — Objective-C implementation

Note: CocoaPods trunk will become read-only on December 2, 2026 and no new versions will be published after that date. We recommend migrating to Swift Package Manager.

Add the following to your Podfile:

pod 'CHTCollectionViewWaterfallLayout'           # Swift (default)
pod 'CHTCollectionViewWaterfallLayout/ObjC'      # Objective-C

Manual

Copy CHTCollectionViewWaterfallLayout.swift (Swift) or CHTCollectionViewWaterfallLayout.h/.m (Objective-C) to your project.

Migrating to v1.0.0

v1.0.0 includes a full rewrite of the Swift implementation. The Objective-C implementation is unchanged. If you are using the Swift version, please review the following breaking changes.

Deployment Target

The minimum deployment target is now iOS 13 / tvOS 13 (was iOS 9 / tvOS 9). Projects targeting earlier versions cannot adopt this release.

Swift Toolchain

swift-tools-version is now 5.9 (was 5.0). Xcode 15+ is required to resolve this package via SPM.

Supplementary View Element Kind

Headers and footers are now created with custom element kind strings (CHTCollectionElementKindSectionHeader / CHTCollectionElementKindSectionFooter) to match the Objective-C implementation. In 0.9.x these constants were marked @available(*, unavailable) and redirected to UICollectionView.elementKindSectionHeader/Footer.

If you register supplementary views, update the element kind:

// Before (0.9.x)
collectionView.register(HeaderView.self,
                        forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,
                        withReuseIdentifier: "Header")

// After (1.0.0)
collectionView.register(HeaderView.self,
                        forSupplementaryViewOfKind: CHTCollectionElementKindSectionHeader,
                        withReuseIdentifier: "Header")

layoutAttributesForSupplementaryView(ofKind:at:) accepts both variants, so layout queries work either way. But layoutAttributesForElements(in:) returns attributes with the CHT-prefixed kind, so any code filtering by representedElementKind must match accordingly.

Return Type Change

layoutAttributesForSupplementaryView(ofKind:at:) now returns UICollectionViewLayoutAttributes? (optional) instead of a non-optional value. It returns nil for unknown element kinds instead of an empty attributes object.

Removed Public delegate Property

The delegate computed property is now private. Access the delegate through collectionView.delegate instead.

Removed Migration Shims

The following @available(*, unavailable, renamed:) declarations from 0.9.x have been removed. If your code still references the old names, rename them:

Removed Replacement
sizeForItemAtIndexPath: sizeForItemAt:
heightForHeaderInSection: heightForHeaderIn:
heightForFooterInSection: heightForFooterIn:
insetForSectionAtIndex: insetsFor:
minimumInteritemSpacingForSectionAtIndex: minimumInteritemSpacingFor:
columnCountForSection: columnCountFor:
CHTCollectionViewWaterfallLayoutItemRenderDirection CHTCollectionViewWaterfallLayout.ItemRenderDirection

New Properties and Delegate Methods

The following are additive (non-breaking) but worth noting:

  • Properties: headerInset, footerInset, minimumContentHeight
  • Delegate methods: insetsForHeaderIn:, insetsForFooterIn:, minimumColumnSpacingFor:

All have sensible defaults and do not require adoption.

How to Use

Both Swift and Objective-C demo projects are included in the Demo/ directory. Read the demo code and the source headers for more information.

Step 1: Configure the Layout

Below are the properties available for customizing the layout. Although they have default values, it is strongly recommended to set at least columnCount to suit your needs.

The itemRenderDirection property controls the order in which items are rendered in subsequent rows: left-to-right, right-to-left, or shortest column first.

Swift

let layout = CHTCollectionViewWaterfallLayout()
layout.columnCount = 2
layout.minimumColumnSpacing = 10
layout.minimumInteritemSpacing = 10
layout.headerHeight = 0
layout.footerHeight = 0
layout.headerInset = .zero
layout.footerInset = .zero
layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
layout.itemRenderDirection = .shortestFirst
layout.minimumContentHeight = 0

Objective-C

CHTCollectionViewWaterfallLayout *layout = [[CHTCollectionViewWaterfallLayout alloc] init];
layout.columnCount = 2;
layout.minimumColumnSpacing = 10;
layout.minimumInteritemSpacing = 10;
layout.headerHeight = 0;
layout.footerHeight = 0;
layout.headerInset = UIEdgeInsetsZero;
layout.footerInset = UIEdgeInsetsZero;
layout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10);
layout.itemRenderDirection = CHTCollectionViewWaterfallLayoutItemRenderDirectionShortestFirst;
layout.minimumContentHeight = 0;

Step 2: Implement the Delegate

Your collection view's delegate (typically your view controller) must conform to CHTCollectionViewDelegateWaterfallLayout and implement the required method. Return the original size of each item:

Swift

func collectionView(_ collectionView: UICollectionView,
                    layout collectionViewLayout: UICollectionViewLayout,
                    sizeForItemAt indexPath: IndexPath) -> CGSize {
  return CGSize(width: imageWidth, height: imageHeight)
}

Objective-C

- (CGSize)collectionView:(UICollectionView *)collectionView
                  layout:(UICollectionViewLayout *)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
  return CGSizeMake(imageWidth, imageHeight);
}

Limitations

  • Only vertical scrolling is supported.
  • No decoration view.

Who Is Using It

Please let me know if your app is using this library. I'm glad to put your app on the list :-)

  • F3PiX F3PiX is a series of apps which gives you a concise, curated collection of pictures by professional (Dutch) photographers according to a specific theme. You can use the pictures freely for your own work.
  • GroupMe for iOS GroupMe - A Home for All the Groups in Your Life.
  • Flickr Access and organize your photos from anywhere.
  • Tumblr Post whatever you want to your Tumblr. Follow other people who are doing the same. You'll probably never be bored again.
  • Funliday The best trip planning app in the world!
  • Imgur Funny GIFs, Memes, and Images!
  • DealPad DealPad gives you access to the UK's hottest Deals, Voucher Codes and Freebies in the palm of your hand.
  • Teespring Shopping Browse and purchase shirts, mugs, totes and more!

License

CHTCollectionViewWaterfallLayout is available under the MIT license. See the LICENSE file for more info.

Changelog

Refer to the Releases page.

About

The waterfall (i.e., Pinterest-like) layout for UICollectionView.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

Packages

 
 
 

Contributors