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

Overview

CHTCollectionViewWaterfallLayout

Carthage compatible Swift Package Manager compatible Version Platform Build Status

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

This layout is inspired by Pinterest.

Screen Shots

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.

Requirements

  • iOS 9+ / tvOS 9+
  • Objective-C or Swift 4.2

How to install

  • CocoaPods

    • Add pod 'CHTCollectionViewWaterfallLayout' to your Podfile.
    • If you prefer Objective-C, pod 'CHTCollectionViewWaterfallLayout/ObjC' is ready for you.
  • Carthage

    • Add github chiahsien/CHTCollectionViewWaterfallLayout to your Cartfile.
  • Swift Package Manager

    • Add it to the dependencies value of your Package.swift.
    dependencies: [
      .package(url: "https://github.com/chiahsien/CHTCollectionViewWaterfallLayout.git", from: "0.9.9")
    ]
    
  • Manual

    • Copy CHTCollectionViewWaterfallLayout.h/m or CHTCollectionViewWaterfallLayout.swift to your project.

How to Use

Read the demo codes and CHTCollectionViewWaterfallLayout.h header file for more information.

Step 1

Below lists the properties for you to customize the layout. Although they have default values, I strongly recommend you to set up at least the columnCount property to suit your needs. The itemRenderDirection property is an enum which decides the order in which your items will be rendered in subsequent rows. For eg. Left-Right | Right-Left | Shortest column filling up first.

@property (nonatomic, assign) NSInteger columnCount;
@property (nonatomic, assign) CGFloat minimumColumnSpacing;
@property (nonatomic, assign) CGFloat minimumInteritemSpacing;
@property (nonatomic, assign) CGFloat headerHeight;
@property (nonatomic, assign) CGFloat footerHeight;
@property (nonatomic, assign) UIEdgeInsets sectionInset;
@property (nonatomic, assign) ItemRenderDirection itemRenderDirection;

Step 2

Your collection view's delegate (which often is your view controller) must conforms to CHTCollectionViewDelegateWaterfallLayout protocol and implements the required method, all you need to do is return the original size of the item:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;

Limitation

  • 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.

Comments
  • Swift 3

    Swift 3

    How did you resolve this ins swift 3 ?

    let yOffset = ((self.columnHeights[section] as AnyObject).object(columnIndex) as AnyObject).doubleValue

    gives me error 'Cannot call value of non-function type 'Any?!''

    (self.columnHeights[section] as AnyObject).enumerateObjects({(object : AnyObject!, idx : NSInteger,pointer :UnsafeMutablePointer) and this one gives error ' Cannot invoke 'enumerateObjects' with an argument list of type '((AnyObject!, NSInteger, UnsafeMutablePointer) -> ())';

    I used Xcode 8 converter and this is the result, thx for help

    opened by SebastianKumor 18
  • Crash on data reload with 0 items and sections

    Crash on data reload with 0 items and sections

    First off, great work on the layout. I use the layout for a couple sections with three or four items each. Each section has a header and the items are populated by data retrieved from a network call. I have a method that removes all objects from the data source and sets everything back to zero. For example, 0 sections, with 0 items. Essentially an empty array. The method looks a bit like this:

    - (IBAction)resetButtonTapped:(id)sender
    {
        [self.dataSource removeAllObjects];
        [self.collectionView reloadData];
    }
    

    Whenever I reset everything back to zero, and call reloadData, the following exception is thrown:

    *** Assertion failure in -[UICollectionViewData layoutAttributesForSupplementaryElementOfKind:atIndexPath:], /SourceCache/UIKit_Sim/UIKit-3318/UICollectionViewData.m:853
    2014-10-19 19:18:22.554 Hord[31192:4215382] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'request for layout attributes for supplementary view CHTCollectionElementKindSectionHeader in section 0 when there are only 0 sections in the collection view'
    

    A similar issue was reported on another custom UICollectionViewLayout here. However, the other layout appears to have some sort of cache invalidation logic built in.

    It looks like the layout object is still trying to return attributes for a header that no longer exists. Any advice you have on resolving this issue is much appreciated. Thanks in advance!

    opened by natenash203 11
  • Performance of layoutAttributesForElementsInRect: is poor when UICollectionView has many thousands of cells

    Performance of layoutAttributesForElementsInRect: is poor when UICollectionView has many thousands of cells

    This function is spending a considerable amount of time calculating the layoutAttributes during scrolling which lowers the frame rate significantly :(

    opened by donholly 10
  • ⚠️The #116 is a new BUG !

    ⚠️The #116 is a new BUG !

    opened by madordie 8
  • Fix for issue when layout is rotated

    Fix for issue when layout is rotated

    @chiahsien We were having issues with the frame vs. bounds values when we rotated the view to support horizontal scrolling (admittedly, I've been meaning to look into adding this support, but we were in a time crunch :) ), and iOS sometimes has a discrepancy between frame and bounds values when adjusting the transform of a view. Let me know if you have any concerns here!

    opened by joshleibsly 8
  • Dynamic Sizing of Header

    Dynamic Sizing of Header

    I am using your layout (fantastic job) however I seem to run into an issue where I want to set the height for the header at runtime. However all your examples show a static size. Is it possible to configure height dynamically at runtime?

    opened by andrewjaykeller 8
  • Fix public headers path for ObjC SwiftPM target

    Fix public headers path for ObjC SwiftPM target

    publicHeadersPath is relative to the path parameter. Without this change, no headers are exposed for consuming libraries and apps to use. I tested this in a sample project to verify. We may want to consider adding demo apps for the two swift package libraries to ensure this can't happen again.

    opened by master-nevi 6
  • get you project from pod under ios5

    get you project from pod under ios5

    I try to import CHTCollectionViewWaterfallLayout using "pod update ", but I get error:

    [!] The platform of the target Pods (iOS 5.0) is not compatible with CHTCollectionViewWaterfallLayout (0.0.1) which has a minimum requirement of iOS 6.0.

    How should I do this right?

    opened by larkin891218 6
  • Not iOS 5 compatible

    Not iOS 5 compatible

    It's not possible to use it on iOS5. Several points:

    • UICollectionViewDelegate and UICollectionViewLayout do not exist on iOS5
    • When used with PSTCollectionView on iOS5 it raises an exception when PSTCollectionView tries to put itself in collectionView property of the layout.
    opened by gsempe 6
  • Pod install does not work with latest version (0.9.3)

    Pod install does not work with latest version (0.9.3)

    The platform of the target `Fishbrain` (iOS 8.0) is not compatible with `CHTCollectionViewWaterfallLayout (0.9.3)`, which does not support `ios`.
    

    Temporary solution was to rollback to old version:

    Lock CHTCollectionViewWaterfallLayout to 0.9.2 in PodsLocal/FIBCollectionViewController/FIBCollectionViewController.podspec.json

    opened by johanlunds 5
  • Items are loading in random order

    Items are loading in random order

    The cards that are being rendered are not in the order of my data array. For eg.: . _ _ _ _ _ . | |1| |2| |3| | | |5| |6| |4| | | |8| |9| |7| | |_ _ _ _ _ .|

    (apologies for the poor ASCII)

    Do I have to set any property to fix this? I was expecting them to render left-right in each row:

    1 2 3 4 5 6 7 8 9 ...

    opened by scorpionking2k5 4
  • (fix) ObjC: unified cell height logic with swift

    (fix) ObjC: unified cell height logic with swift

    I realized that the SWIFT and ObjC packages differ in cell height logic.

    The SWIFT version will set the height of the cell no matter what and will set the width when it's bigger than 0, otherwise it will set it to 50% of the screen width.

    On ObjC on the other hand it will only set the height if the width is also bigger than 0.

    The logic in Swift is here and the logic in ObjC is here

    opened by DanijelBojcic 0
  • `minimumColumnSpacing`  is ambiguous in  Swift and Objective-C version

    `minimumColumnSpacing` is ambiguous in Swift and Objective-C version

    Objective-C:

    - (CGFloat)itemWidthInSectionAtIndex:(NSInteger)section {
      UIEdgeInsets sectionInset;
      if ([self.delegate respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)]) {
        sectionInset = [self.delegate collectionView:self.collectionView layout:self insetForSectionAtIndex:section];
      } else {
        sectionInset = self.sectionInset;
      }
      CGFloat width = self.collectionView.bounds.size.width - sectionInset.left - sectionInset.right;
      NSInteger columnCount = [self columnCountForSection:section];
    
      CGFloat columnSpacing = self.minimumColumnSpacing;
      if ([self.delegate respondsToSelector:@selector(collectionView:layout:minimumColumnSpacingForSectionAtIndex:)]) {
        columnSpacing = [self.delegate collectionView:self.collectionView layout:self minimumColumnSpacingForSectionAtIndex:section];
      }
    
      return CHTFloorCGFloat((width - (columnCount - 1) * columnSpacing) / columnCount);
    }
    

    Swift:

        public func itemWidth(inSection section: Int) -> CGFloat {
            let columnCount = self.columnCount(forSection: section)
            let spaceColumCount = CGFloat(columnCount - 1)
            let width = collectionViewContentWidth(ofSection: section)
            return floor((width - (spaceColumCount * minimumColumnSpacing)) / CGFloat(columnCount))
        }
    

    In Swift version, collectionView:layout:minimumColumnSpacingForSectionAtIndex not be called in real time. minimumColumnSpacing for section not work.

    opened by HY558 0
  • Ambiguous inference of Objective-C name for instance method

    Ambiguous inference of Objective-C name for instance method

    `extension BlogPostVC: CHTCollectionViewDelegateWaterfallLayout {

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let width = (self.collectionView!.frame.width / 2 ) - 5 // create a cell size from the image size, and return the size if appStorage.userData?.userType == .admin && indexPath.row == 0 {

            return CGSize(width: width, height: 130)
        }
        else {
            
            return CGSize(width: width, height: 300) //blogs[indexPath.item].imageHeightFormatted
        }
    }
    
    //MARK: - CollectionView Waterfall Layout Delegate Methods (Required)
    

    } `

    opened by naveedmcs 1
  • 【Crash】collectionView?.scrollToItem(at: .init(row: 0, section: 0), at: .top, animated: true)

    【Crash】collectionView?.scrollToItem(at: .init(row: 0, section: 0), at: .top, animated: true)

    Thread 1: "Attempted to scroll the collection view to an out-of-bounds item (0) when there are only 0 items in section 0. Collection view: <UICollectionView: 0x7fa1680a3600; frame = (0 0; 428 751); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x6000012ff210>; layer = <CALayer: 0x600001c1e420>; contentOffset: {0, 0}; contentSize: {428, 10}; adjustedContentInset: {0, 0, 44, 0}; layout: <CHTCollectionViewWaterfallLayout.CHTCollectionViewWaterfallLayout: 0x7fa165f25090>; dataSource: <HomeListController: 0x7fa165f24b00>>."

    opened by DreamRui 0
  • error: Compiling IB documents for earlier than iOS 7 is no longer supported. [12]

    error: Compiling IB documents for earlier than iOS 7 is no longer supported. [12]

    /* com.apple.ibtool.document.errors */ /Users/admin/Downloads/CHTCollectionViewWaterfallLayout-develop/Demo/Objective-C/Demo/en.lproj/MainStoryboard_iPhone.storyboard:global: error: Compiling IB documents for earlier than iOS 7 is no longer supported. [12]

    opened by AAChartModel 1
Releases(0.9.10)
  • 0.9.10(Dec 3, 2021)

  • 0.9.9(Dec 1, 2021)

    • Support SPM.
    • Replace Travis CI with GitHub action.
    • Update both ObjC and Swift demo.
    • Re-organize source codes
    • Bump minimum supported iOS version to 9.0.
    • Change Cocoapods default spec from ObjC to Swift.
    Source code(tar.gz)
    Source code(zip)
  • 0.9.7(Sep 5, 2017)

  • 0.9.6(May 24, 2017)

  • 0.9.5(Aug 23, 2016)

  • 0.9.4(May 2, 2016)

  • 0.9.2(Aug 9, 2015)

  • 0.9.1(May 15, 2015)

  • 0.9(May 7, 2015)

    • Minimum content height configuration (#84)
    • Minimum column spacing per section configuration (#86)
    • Fix a crash when no data and no section (#76, #93)
    • Swift update (#77, #92, #98)
    • Long cell disappearing fix (#78)
    • Fix height calculation (#79)
    • Pixel perfect (#83)
    Source code(tar.gz)
    Source code(zip)
  • 0.8(Sep 21, 2014)

    • Adding a configuration option to determine the order of rendering the items. Options include Left-to-Right | Right-to-Left | Shortest column first (existing default).
    • New demo screenshots
    • Custom column count per section
    • Swift version
    • Code cleanup
    Source code(tar.gz)
    Source code(zip)
  • 0.7(May 6, 2014)

  • 0.6(Apr 2, 2014)

    • [Add] Add minimumColumnSpacing and minimumInteritemSpacing properties.
    • [Remove] Remove itemWidth property. The layout object will calculate a proper item width automatically.
    • [Change] Rename delegate method - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout heightForItemAtIndexPath:(NSIndexPath *)indexPath to - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath. It should return original size for each item.
    • [Fix] Section header and/or footer should work properly.
    • [Fix] Use sectionInset correctly.
    Source code(tar.gz)
    Source code(zip)
  • 0.5(Apr 2, 2014)

    • [Add] Multiple sections.
    • [Add] Header and/or footer for section.
    • [Add] More properties and delegation methods.
    • [Change] Remove delegate property, your collectionView's delegate MUST conforms to <CHTCollectionViewDelegateWaterfallLayout> protocol.
    Source code(tar.gz)
    Source code(zip)
Owner
Nelson
Full-time iOS manager and developer, check out my LinkedIn page for more information. https://www.linkedin.com/in/tainelson
Nelson
A drop-in mosaic collection view layout with a focus on simple customizations.

FMMosaicLayout is a mosiac collection view layout. There are a great number of media-based iOS applications that use UICollectionViewFlowLayout withou

Fluid Media Inc. 591 Dec 14, 2022
A mosaic collection view layout inspired by Lightbox's Algorithm, written in Swift 🔶

TRMosaicLayout A mosaic collection view layout inspired by Lightbox's Algorithm. This is a swift implementation/extension of @fmitech's FMMosaicLayout

Vincent Le 252 Nov 23, 2022
A CollectionView Layout displaying a slanted cells

CollectionViewSlantedLayout is a subclass of the UICollectionViewLayout allowing the display of slanted cells in a UICollectionView. Features Pure Swi

Yassir Barchi 2.2k Dec 27, 2022
BouncyLayout is a collection view layout that makes your cells bounce.

BouncyLayout is a collection view layout that makes your cells bounce. Features Pure Swift 5. Works with every UICollectionView. Horizontal and vertic

Robert-Hein Hooijmans 4.2k Jan 3, 2023
AZSafariCollectionViewLayout is replica of safari browser history page layout. very easy to use, IBInspectable are given for easy integration

AZSafariCollectionViewLayout Features iOS Safari history view layout IBDesignAble for properties Few minutes integration Installation CocoaPods CocoaP

Afroz Zaheer 211 Dec 6, 2022
A waterfall grid layout view for SwiftUI.

WaterfallGrid A waterfall grid layout view for SwiftUI. Features Irregular grid of content. Columns number different per device orientation. Spacing a

Paolo Leonardi 1.9k Jan 7, 2023
SwiftUI views that arrange their children in a Pinterest-like layout

SwiftUI Masonry SwiftUI views that arrange their children in a Pinterest-like layout. HMasonry A view that arranges its children in a horizontal mason

Ciaran O'Brien 88 Dec 27, 2022
🥺Pinterest Layout Tutorial

PinterestTutorial-iOS ?? Pinterest Layout Tutorial 이미지 크기에 따라서 동적으로 셀의 레이아웃을 설정하는 핀터레스트 레이아웃 구현해 보았다. 완성 코드 UICollectionViewDelegateFlowLayout 의 서브클래스

Hyungyu Kim 6 May 10, 2022
🔍 Awesome fully customize search view like Pinterest written in Swift 5.0 + Realm support!

YNSearch + Realm Support Updates See CHANGELOG for details Intoduction ?? Awesome search view, written in Swift 5.0, appears search view like Pinteres

Kyle Yi 1.2k Dec 17, 2022
A Pinterest-like segment control with masking animation.

PinterestSegment A Pinterest-like segment control with masking animation. Requirements iOS 8.0+ Xcode 9.0 Swift 4.0 Installation CocoaPods You can use

TBXark 672 Dec 20, 2022
🔍 Awesome fully customize search view like Pinterest written in Swift 5.0 + Realm support!

YNSearch + Realm Support Updates See CHANGELOG for details Intoduction ?? Awesome search view, written in Swift 5.0, appears search view like Pinteres

Kyle Yi 1.2k Dec 17, 2022
This is a Swift based demo project to show how to make the transition Pinterest liked.

PinterestSwift Compatible with Xcode 11 / Swift 5.0 This is a Swift based demo project to show how to make the transition Pinterest 2.0+ liked. Refer

Nicholas Tau 1.9k Dec 20, 2022
Context menu similar to the one in the Pinterest iOS app

VLDContextSheet A clone of the Pinterest iOS app context menu. Example Usage VLDContextSheetItem *item1 = [[VLDContextSheetItem alloc] initWithTitle:

Vladimir Angelov 173 Mar 28, 2022
A deep copy of Pinterest in Swift

Demo YouTube: Demo (2 minutes) 优酷:http://v.youku.com/v_show/id_XMzE3OTc5NDY2MA==.html?spm=a2h3j.8428770.3416059.1 The app is actually smoother than sh

Andy Tong 73 Sep 14, 2022
🔄 GravitySlider is a beautiful alternative to the standard UICollectionView flow layout.

GravitySliderFlowLayout Made by Applikey Solutions Find this project on Dribbble Table of Contents Purpose Supported OS & SDK Versions Installation Us

Applikey Solutions 958 Dec 23, 2022
Made in Swift - Tag layout for UICollectionView supporting 3 types of alignments - Left || Centre || Right

TagCellLayout About Its an ui-collection-view LAYOUT class that takes care of all the logic behind making tags like layout using UICollectionView. It

Ritesh Gupta 346 Jan 1, 2023
Pull-to-refresh animation in UICollectionView with a sticky header flow layout, written in Swift :large_orange_diamond:

ReplaceAnimation Implementation of Zee Young's Dribbble animation (https://dribbble.com/shots/2067564-Replace) Info I really liked Zee Young's animati

Alex Türk 957 Sep 13, 2022
UICollectionView layout for presenting of the overlapping cells.

StickyCollectionView UICollectionView layout for presenting of the overlapping cells. Objective-C version here Checkout demo Overview Installation Man

Bogdan Matveev 325 Oct 11, 2022
Made in Swift - Tag layout for UICollectionView supporting 3 types of alignments - Left || Centre || Right

TagCellLayout About Its an ui-collection-view LAYOUT class that takes care of all the logic behind making tags like layout using UICollectionView. It

Ritesh Gupta 346 Jan 1, 2023
Pintrest flow layout UICollectionView

pintrest-flow-layout Pintrest flow layout UICollectionView You need to adjust the coulmns number you need after setting the layout var layout

Anas Almomany 11 Nov 8, 2022