UICollectionView

extension UICollectionView

Delegate and DataSource

UICollectionView closures make it easy to implement UICollectionViewDelegate and UICollectionViewDataSource protocol methods in an organized way. The following is an example of a simple collection view that displays strings in a basic cell.

func loadCollectionView() {
    collectionView.register(MyCustomCollectionViewCell.self, forCellWithReuseIdentifier: "Cell")

    collectionView
        .numberOfItemsInSection { _ in
            countries.count
        }.cellForItemAt { indexPath in
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! MyCustomCollectionViewCell
            cell.textLabel.text = countries[indexPath.item]
            return cell
        }.didSelectItemAt {
            print("\(countries[$0.item]) selected")
        }.reloadData()
}

Arrays

These operations are common. Usually, they involve populating the UICollectionView with the values from an array. Closures framework gives you a convenient way to pass your array to the collection view, so that it can perform the boilerplate operations for you, especially the ones that are required to make the collection view perform at a basic level.

Important

Please remember that Swift Arrays are value types. This means that they are copied when mutated. When the values or sequence of your array changes, you will need to call addFlowElements again, just before you call reloadData().
func loadCollectionView(countries: [String]) {
    collectionView
        .addFlowElements(countries, cell: MyCustomCollectionViewCell.self) { country, cell, index in
            cell.textLabel.text = country
    }.reloadData()

    /**
     This also allows you to override any default behavior so
     you aren't overly committed, even though you're initially binding everything
     to the `Array`.
     */
    collectionView.didSelectItemAt {
        print("\(countries[$0.item]) selected from array")
    }
}
  • This method defaults many of the boilerplate callbacks needed to populate a UICollectionView when using an Array as a data source. The defaults that this method takes care of:

    • Registers the cell’s class and reuse identifier with a default value
    • Optionally uses a cellNibName value to create the cell from a nib file from the main bundle
    • Handles cell dequeueing and provides a reference to the cell in the item closure for you to modify in place.
    • Provides the number of sections
    • Provides the number of items

    This method simply sets basic default behavior. This means that you can override the default collection view handlers after this method is called. However, remember that order matters. If you call this method after you override the numberOfSectionsIn callback, for instance, the closure you passed into numberOfSectionsIn will be wiped out by this method and you will have to override that closure handler again.

    Important

    Please remember that Swift Arrays are value types. This means that they are copied when mutaded. When the values or sequence of your array changes, you will need to call this method again, just before you call reloadData(). If you have a lot of collection view customization in addtion to a lot of updates to your array, it is more appropriate to use the individual closure handlers instead of this method.

    An example of calling this method:

    collectionView.addFlowElements(<#myArray#>, cell: <#MyUICollectionViewCellClass#>) { element, cell, index in
        cell.imageView.image = <#T##someImage(from: element)##UIImage#>
    }
    

    Declaration

    Swift

    @discardableResult
    public func addFlowElements<Element,Cell>(
        _ elements: [Element],
        cell: Cell.Type,
        cellNibName: String? = nil,
        item: @escaping (_ element: Element, _ cell: inout Cell,_ index: Int) -> Void) -> Self
        where Cell: UICollectionViewCell

    Parameters

    array

    An Array to be used for each item.

    cell

    A type of cell to use when calling dequeueReusableCell(withReuseIdentifier:for:)

    cellNibName

    If non-nil, the cell will be dequeued using a nib with this name from the main bundle

    item

    A closure that’s called when a cell is about to be shown and needs to be configured.

    Return Value

    itself so you can daisy chain the other datasource calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:shouldHighlightItemAt:) method

    Declaration

    Swift

    @discardableResult
    public func shouldHighlightItemAt(handler: @escaping (_ indexPath: IndexPath) -> Bool) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:didHighlightItemAt:) method

    Declaration

    Swift

    @discardableResult
    public func didHighlightItemAt(handler: @escaping (_ indexPath: IndexPath) -> Void) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:didUnhighlightItemAt:) method

    Declaration

    Swift

    @discardableResult
    public func didUnhighlightItemAt(handler: @escaping (_ indexPath: IndexPath) -> Void) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:shouldSelectItemAt:) method

    Declaration

    Swift

    @discardableResult
    public func shouldSelectItemAt(handler: @escaping (_ indexPath: IndexPath) -> Bool) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:shouldDeselectItemAt:) method

    Declaration

    Swift

    @discardableResult
    public func shouldDeselectItemAt(handler: @escaping (_ indexPath: IndexPath) -> Bool) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:didSelectItemAt:) method

    Declaration

    Swift

    @discardableResult
    public func didSelectItemAt(handler: @escaping (_ indexPath: IndexPath) -> Void) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:didDeselectItemAt:) method

    Declaration

    Swift

    @discardableResult
    public func didDeselectItemAt(handler: @escaping (_ indexPath: IndexPath) -> Void) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:willDisplay:forItemAt:) method

    Declaration

    Swift

    @discardableResult
    public func willDisplay(handler: @escaping (_ cell: UICollectionViewCell, _ indexPath: IndexPath) -> Void) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:willDisplaySupplementaryView:forElementKind:at:) method

    Declaration

    Swift

    @discardableResult
    public func willDisplaySupplementaryView(handler: @escaping (_ elementKind: String, _ indexPath: IndexPath) -> Void) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:didEndDisplaying:forItemAt:) method

    Declaration

    Swift

    @discardableResult
    public func didEndDisplaying(handler: @escaping (_ cell: UICollectionViewCell, _ indexPath: IndexPath) -> Void) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:didEndDisplayingSupplementaryView:forElementOfKind:at:) method

    Declaration

    Swift

    @discardableResult
    public func didEndDisplayingSupplementaryView(handler: @escaping (_ elementKind: String, _ indexPath: IndexPath) -> Void) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:shouldShowMenuForItemAt:) method

    Declaration

    Swift

    @discardableResult
    public func shouldShowMenuForItemAt(handler: @escaping (_ indexPath: IndexPath) -> Bool) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:canPerformAction:forItemAt:withSender:) method

    Declaration

    Swift

    @discardableResult
    public func canPerformAction(handler: @escaping (_ action: Selector, _ indexPath: IndexPath, _ sender: Any?) -> Bool) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:performAction:forItemAt:withSender:) method

    Declaration

    Swift

    @discardableResult
    public func performAction(handler: @escaping (_ action: Selector, _ indexPath: IndexPath, _ sender: Any?) -> Void) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:transitionLayoutForOldLayout:newLayout:) method

    Declaration

    Swift

    @discardableResult
    public func transitionLayoutForOldLayout(handler: @escaping (_ fromLayout: UICollectionViewLayout, _ toLayout: UICollectionViewLayout) -> UICollectionViewTransitionLayout) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:canFocusItemAt:) method

    Declaration

    Swift

    @discardableResult
    public func canFocusItemAt(handler: @escaping (_ indexPath: IndexPath) -> Bool) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:shouldUpdateFocusIn:) method

    Declaration

    Swift

    @discardableResult
    public func shouldUpdateFocusIn(handler: @escaping (_ context: UICollectionViewFocusUpdateContext) -> Bool) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:didUpdateFocusIn:with:) method

    Declaration

    Swift

    @discardableResult
    public func didUpdateFocusIn(handler: @escaping (_ context: UICollectionViewFocusUpdateContext, _ coordinator: UIFocusAnimationCoordinator) -> Void) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s indexPathForPreferredFocusedVies(in:) method

    Declaration

    Swift

    @discardableResult
    public func indexPathForPreferredFocusedViewIn(handler: @escaping () -> IndexPath?) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:targetIndexPathForMoveFromItemAt:toProposedIndexPath:) method

    Declaration

    Swift

    @discardableResult
    public func targetIndexPathForMoveFromItemAt(handler: @escaping (_ originalIndexPath: IndexPath, _ proposedIndexPath: IndexPath) -> IndexPath) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:targetContentOffsetForProposedContentOffset:) method

    Declaration

    Swift

    @discardableResult
    public func targetContentOffsetForProposedContentOffset(handler: @escaping (_ proposedContentOffset: CGPoint) -> CGPoint) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegate’s collectionView(_:shouldSpringLoadItemAt:with:) method

    Declaration

    Swift

    @available(iOS 11, *)
    @discardableResult
    public func shouldSpringLoadItemAt(handler: @escaping (_ indexPath: IndexPath, _ context: UISpringLoadedInteractionContext) -> Bool) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDataSource’s collectionView(_:numberOfItemsInSection:) method

    Declaration

    Swift

    @discardableResult
    public func numberOfItemsInSection(handler: @escaping (_ section: Int) -> Int) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent dataSource method

    Return Value

    itself so you can daisy chain the other dataSource calls

  • Equivalent to implementing UICollectionViewDataSource’s collectionView(_:cellForItemAt:) method

    Declaration

    Swift

    @discardableResult
    public func cellForItemAt(handler: @escaping (_ indexPath: IndexPath) -> UICollectionViewCell) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent dataSource method

    Return Value

    itself so you can daisy chain the other dataSource calls

  • Equivalent to implementing UICollectionViewDataSource’s numberOfSections(in:) method

    Declaration

    Swift

    @discardableResult
    public func numberOfSectionsIn(handler: @escaping () -> Int) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent dataSource method

    Return Value

    itself so you can daisy chain the other dataSource calls

  • Equivalent to implementing UICollectionViewDataSource’s collectionView(_:viewForSupplementaryElementOfKind:at:) method

    Declaration

    Swift

    @discardableResult
    public func viewForSupplementaryElementOfKind(handler: @escaping (_ kind: String, _ indexPath: IndexPath) -> UICollectionReusableView) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent dataSource method

    Return Value

    itself so you can daisy chain the other dataSource calls

  • Equivalent to implementing UICollectionViewDataSource’s collectionView(_:canMoveItemAt:) method

    Declaration

    Swift

    @discardableResult
    public func canMoveItemAt(handler: @escaping (_ indexPath: IndexPath) -> Bool) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent dataSource method

    Return Value

    itself so you can daisy chain the other dataSource calls

  • Equivalent to implementing UICollectionViewDataSource’s collectionView(_:moveItemAt:to:) method

    Declaration

    Swift

    @discardableResult
    public func moveItemAt(handler: @escaping (_ sourceIndexPath: IndexPath, _ destinationIndexPath: IndexPath) -> Void) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent dataSource method

    Return Value

    itself so you can daisy chain the other dataSource calls

  • Equivalent to implementing UICollectionViewDataSource’s indexTitles(for:) method

    Declaration

    Swift

    @discardableResult
    public func indexTitlesFor(handler: @escaping () -> [String]) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent dataSource method

    Return Value

    itself so you can daisy chain the other dataSource calls

  • Equivalent to implementing UICollectionViewDataSource’s collectionView(_:indexPathForIndexTitle:at:) method

    Declaration

    Swift

    @discardableResult
    public func indexPathForIndexTitle(handler: @escaping (_ title: String, _ index: Int) -> IndexPath) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent dataSource method

    Return Value

    itself so you can daisy chain the other dataSource calls

  • Equivalent to implementing UICollectionViewDelegateFlowLayout’s collectionView(_:layout:sizeForItemAt:) method

    Declaration

    Swift

    @discardableResult
    public func sizeForItemAt(handler: @escaping (_ indexPath: IndexPath) -> CGSize) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegateFlowLayout’s collectionV(_:layout:insetForSectionAt:) method

    Declaration

    Swift

    @discardableResult
    public func insetForSectionAt(handler: @escaping (_ section: Int) -> UIEdgeInsets) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegateFlowLayout’s collectionView(_:layout:minimumLineSpacingForSectionAt:) method

    Declaration

    Swift

    @discardableResult
    public func minimumLineSpacingForSectionAt(handler: @escaping (_ section: Int) -> CGFloat) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegateFlowLayout’s collectionView(_:layout:minimumInteritemSpacingForSectionAt:) method

    Declaration

    Swift

    @discardableResult
    public func minimumInteritemSpacingForSectionAt(handler: @escaping (_ section: Int) -> CGFloat) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegateFlowLayout’s collectionView(_:layout:referenceSizeForHeaderInSection:) method

    Declaration

    Swift

    @discardableResult
    public func referenceSizeForHeaderInSection(handler: @escaping (_ section: Int) -> CGSize) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Equivalent to implementing UICollectionViewDelegateFlowLayout’s collectionView(_:layout:referenceSizeForFooterInSection:) method

    Declaration

    Swift

    @discardableResult
    public func referenceSizeForFooterInSection(handler: @escaping (_ section: Int) -> CGSize) -> Self

    Parameters

    handler

    The closure that will be called in place of its equivalent delegate method

    Return Value

    itself so you can daisy chain the other delegate calls

  • Clears any delegate/dataSource closures that were assigned to this UICollectionView. This cleans up memory as well as sets the delegate/dataSource properties to nil. This is typically only used for explicit cleanup. You are not required to call this method.

    Declaration

    Swift

    @objc
    override public func clearClosureDelegates()