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 SwiftArray
s 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 intonumberOfSectionsIn
will be wiped out by this method and you will have to override that closure handler again.Important
Please remember that SwiftArray
s 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()