CollectionView
open class CollectionView : ScrollView, NSDraggingSource
A Collection View manages the presentation of items, your app’s main job is to provide the data that those items are to represent.
A collection view gets its data from the data source, which is an object that conforms to the CollectionViewDataSource protocol. Data provided by the data source is represented items, which can also be organized into sections, and ultimately displayed as cells.
Gathings Data
The data source only has 3 requirements, provide the number of sections, the number of items, and a cell for each item. For performance, cells in a collection view are reusable since only a subset of all the items will often be visbile.
Before you can load a cell, you need to register the cells you will need to represet your data. Cells can be registered from a nib or from a class using register(class:forCellWithReuseIdentifier:)
or register(nib:forCellWithReuseIdentifier:)
. The reuse identifier will later be use to get instances of the cell.
To create the cells for each item in your data, implement the data source method func collectionView(_:cellForItemAt:) -> CollectionViewCell
. In here you will call dequeueReusableCell(withReuseIdentifier:for:)
which will load an instance of the cell your previously registered for that resuse identifier. After you have dequeued the cell, update it as needed to properly represent the object at the given index path in your data, then return it.
Laying Out Items
After the data source has provided all the cells to be displayed, the collection view looks to its CollectionViewLayout to determine where to place each one. The base layout object is designed to be subclassed to generate layout information for different use cases. The goal of a layout is to be able to provide information about the layout to the collection view quickly, this inlcudes the location of each cell, the overall size of all the items, etc.
The following layouts are provided for common uses, for more custom layouts, create a custom CollectionViewLayout subclass.
- CollectionViewColumnLayout
- CollectionViewListLayout
- CollectionViewFlowLayout
- CollectionViewHorizontalLayout
-
The object that acts as the delegate to the collection view
Declaration
Swift
@objc public weak var delegate: CollectionViewDelegate?
-
The object that provides data for the collection view
Declaration
Swift
public weak var dataSource: CollectionViewDataSource?
-
The content view in which all cells and views are displayed
Declaration
Swift
public var contentDocumentView: CollectionViewDocumentView { get }
-
Register a class to be initialized when loading reusable cells
Declaration
Swift
public func register(class cellClass: CollectionViewCell.Type, forCellWithReuseIdentifier identifier: String)
Parameters
cellClass
A CollectionViewCell subclass
identifier
A reuse identifier to deque cells of this class
-
Register a nib to be loaded as reusable cells
Declaration
Swift
public func register(nib: NSNib, forCellWithReuseIdentifier identifier: String)
Parameters
nib
The nib for the cell
identifier
A reuse identifier to deque cells from this nib
-
Register a class to be initialized when loading reusable supplementary views
Declaration
Swift
public func register(class viewClass: CollectionReusableView.Type, forSupplementaryViewOfKind kind: String, withReuseIdentifier identifier: String)
Parameters
viewClass
A CollectionReusableview subclass
elementKind
The kind of element the class represents
identifier
A reuse identifier to deque views of this class
-
Register a nib to be loaded as a supplementary view
Note
The nib must contain a single view whose class is set to CollectionReusableview.
Declaration
Swift
public func register(nib: NSNib, forSupplementaryViewOfKind elementKind: String, withReuseIdentifier identifier: String)
Parameters
nib
The nib for the view
elementKind
The kind of element this nib represents
identifier
A reuse identifier to deque views from this nib
-
Retrieve a cell for a given reuse identifier and index path.
If no reusable cell is available, one is created from the registered class/nib.
Declaration
Swift
public final func dequeueReusableCell(withReuseIdentifier identifier: String, for indexPath: IndexPath) -> CollectionViewCell
Parameters
identifier
The reuse identifier
indexPath
The index path specifying the location of the supplementary view to load.
Return Value
A valid CollectionReusableView
-
Returns a reusable supplementary view located by its identifier and kind.
Declaration
Swift
public final func dequeueReusableSupplementaryView(ofKind elementKind: String, withReuseIdentifier identifier: String, for indexPath: IndexPath) -> CollectionReusableView
Parameters
elementKind
The kind of supplementary view to retrieve. This value is defined by the layout object. This parameter must not be nil.
identifier
The reuse identifier for the specified view.
indexPath
The index path specifying the location of the cell to load
Return Value
A valid CollectionViewCell
-
A view atop the collection view used to display non-scrolling accessory views
Declaration
Swift
public var floatingContentView: NSView { get }
-
Adds the given view to the floating content view
Declaration
Swift
public func addAccessoryView(_ view: NSView)
Parameters
view
The view to add
-
Returns the number of sections displayed by the collection view.
Declaration
Swift
public var numberOfSections: Int { get }
Return Value
The number of sections
-
Returns the number of items in the specified section.
Declaration
Swift
public func numberOfItems(in section: Int) -> Int
Parameters
section
The index of the section for which you want a count of the items.
Return Value
The number of items in the specified section
-
Reloads all the data and views in the collection view
Declaration
Swift
open func reloadData()
-
The layout used to organize the collected view’s items.
Note
Assigning a new layout object to this property does NOT apply the layout to the collection view. CallreloadData()
orreloadLayout(_:)
to do so.Declaration
Swift
public var collectionViewLayout: CollectionViewLayout { get set }
-
The visible rect of the document view that is visible
Declaration
Swift
public var contentVisibleRect: CGRect { get }
-
The total size of all items/views
Declaration
Swift
open override var contentSize: NSSize { get }
-
The offset of the content view
Declaration
Swift
public var contentOffset: CGPoint { get set }
-
Force layout of all items, not just those in the visible content area
Note
This is not recommended for large data sets. It can be useful for smaller collection views to better manage transitions/animations.Declaration
Swift
public var prepareAll: Bool
-
Returns the frame for the specified section
Declaration
Swift
open func frameForSection(at index: Int) -> CGRect?
Parameters
indexPath
The index path of the section for which you want the frame
-
Reload the data (section & item counts) when the collectionView bounds change. Defaults to false.
Note
This will only be applied if the layout is also invalidated via
shouldInvalidateLayout(forBoundsChange:)
Discussion: Set to
true
if the number of sections or items per section can change depending on the collection view’s size For example if you want to limit the size of a section but maintain item size, you can calculate the number of items that will fit in the section based on the size of the collection view and return that value in collectionView(_:numberOfItemsIn:) from the collection views data source.+----------+ +-----------------+ | | | | | +----+ | | +----+ +----+ | | | | | | | | | | | | | | | | | | | | | | +----+ | +--> | +----+ +----+ | | | | | +----------+ +-----------------+ |Section 2 | |Section 2 | +----------+ +-----------------+ | | | | +----------+ +-----------------+
Declaration
Swift
public var reloadDataOnBoundsChange: Bool
-
A Boolean value indicating whether the collection view layout should be reloaded on the next view layout.
needsLayout
is also if needed.Declaration
Swift
open var needsLayoutReload: Bool { get set }
-
Reload the collection view layout and apply the updated frames to the cells/views.
Declaration
Swift
public func reloadLayout(_ animated: Bool, scrollPosition: CollectionViewScrollPosition = .nearest, completion: AnimationCompletion? = nil)
Parameters
animated
If the layout should be animated
scrollPosition
Where (if any) the scroll position should be pinned
-
Returns true if the collection view is currently scrolling
Declaration
Swift
public internal(set) var isScrolling: Bool
-
Returns the current velocity of a scroll in points/second
Declaration
Swift
public private(set) var scrollVelocity: CGPoint
-
Returns the peak valocity of a scroll during the last scrolling session
Example Usage
If your cells require complex loading that may slow scrolling performance,
peakScrollVelocity
can be used to determine if the cell content should be reduced or delayed until after the scrolling ends.For example in CollectionViewCell
override func viewDidDisplay() { if self.collectionView?.isScrolling != true || (self.collectionView?.peakScrollVelocity.maxAbsVelocity ?? 0) < 200 { // load complex content } else { // Wait until we are done scrolling } } func loadContent() { Do complex loading }
Then, in your collection view’s delegate
func collectionViewDidEndScrolling(_ collectionView: CollectionView, animated: Bool) { guard collectionView.peakScrollVelocity.maxAbsVelocity > 200 else { return } for ip in collectionView.indexPathsForVisibleItems { if let c = collectionView.cellForItem(at:ip) as? MyCellClass { c.loadContent } } }
Declaration
Swift
public private(set) var peakScrollVelocity: CGPoint
-
Returns the lowest index path of all visible items
Declaration
Swift
open var indexPathsForVisibleSections: [IndexPath] { get }
-
Returns the lowest index path of all visible items
Declaration
Swift
open var indexPathForFirstVisibleItem: IndexPath? { get }
-
Same as indexPathForFirstVisibleItem but doesn’t ask the delegate for a suggestion. This is a convenient variable to use in collectionViewLayoutAnchor(_:) but asking the delegate within is not possibe.
Declaration
Swift
open var _indexPathForFirstVisibleItem: IndexPath? { get }
-
The duration of animations when performing animated layout changes
Declaration
Swift
public var animationDuration: TimeInterval
-
Perform multiple updates to be applied together
Declaration
Swift
public func performBatchUpdates(_ updates: (() -> Void), completion: AnimationCompletion?)
Parameters
updates
A closure in which to apply the desired changes
completion
A closure to call when the animation finished
-
Insert sections at the given indexes
Declaration
Swift
public func insertSections(_ sections: IndexSet, animated: Bool)
Parameters
sections
The sections to insert
animated
If the update should be animated
Note
If called within performBatchUpdate(_:completion:) sections should be the final indexes after other updates are applied -
Remove sections and their items
Declaration
Swift
public func deleteSections(_ sections: IndexSet, animated: Bool)
Parameters
sections
The sections to delete
Note
If called within performBatchUpdate(_:completion:) sections should be the index prior to any other updatesanimated
If the update should be animated
-
Move a section and its items
Note
If called within performBatchUpdate(_:completion:):
Source should be the index prior to any other updates
Destination should be the final index after all other updates
Declaration
Swift
public func moveSection(_ section: Int, to newSection: Int, animated: Bool)
Parameters
section
The source index of the section to move
newSection
The destination index to move the section to
animated
If the move should be animated
-
Insert items at specific index paths
Declaration
Swift
public func insertItems(at indexPaths: [IndexPath], animated: Bool)
Parameters
indexPaths
The index paths at which to insert items.
animated
If the insertion should be animated
-
Deletes the items at the specified index paths.
Declaration
Swift
public func deleteItems(at indexPaths: [IndexPath], animated: Bool)
Parameters
indexPaths
The index paths for the items you want to delete
animated
If the updates should be animated
-
Reload the items and the given index paths.
The cells will be reloaded, asking the data source for the cell to replace with.
Declaration
Swift
public func reloadItems(at indexPaths: [IndexPath], animated: Bool)
Parameters
indexPaths
The index paths for the items you want to reoad
animated
If the updates should be animated
-
Moves the item from it’s current index path to another
Declaration
Swift
public func moveItem(at indexPath: IndexPath, to destinationIndexPath: IndexPath, animated: Bool)
Parameters
indexPath
The index path for the item to move
destinationIndexPath
The index path to move the item to
animated
If the update should be animated
-
If true, the delegate’s
collectionView(_:,mouseMovedToSection:)
will be notified when the cursor is within a section frameDeclaration
Swift
public var trackSectionHover: Bool { get set }
-
If the collection view should allow selection of its items
Declaration
Swift
public var allowsSelection: Bool
-
Determine how item selections are managed
- normal: Clicking an item selects the item and deselects others (given no modifier keys are used)
- multi: Clicking an item will add it to the selection, clicking again will deselect it
Declaration
Swift
public enum SelectionMode
-
Determines what happens when an item is clicked
Declaration
Swift
public var selectionMode: CollectionView.SelectionMode
-
Allows the selection of multiple items via modifier keys (command & shift) (default true)
Declaration
Swift
public var allowsMultipleSelection: Bool
-
If true, clicking empty space will deselect all items (default true)
Declaration
Swift
public var allowsEmptySelection: Bool
-
If true, programatic changes will be reported to the delegate (i.e. selections)
Declaration
Swift
public var notifyDelegate: Bool
-
If true, selecting an already selected item will notify the delegate (default true)
Declaration
Swift
public var repeatSelections: Bool
-
The index path of the highlighted item, if any
Declaration
Swift
public internal(set) var indexPathForHighlightedItem: IndexPath? { get set }
-
Manually set the highlighted item reguardless of the cursor location
This can be use to adust the highlighted item in response to key events
Declaration
Swift
public func highlightItem(at indexPath: IndexPath?, animated: Bool)
Parameters
indexPath
The index path of the item to highlight
animated
If the change should be animated
-
Returns the index paths for all selected items
Declaration
Swift
public final var indexPathsForSelectedItems: Set<IndexPath> { get }
-
Returns the index paths for all selected items ordered from first to last
Declaration
Swift
public final var sortedIndexPathsForSelectedItems: [IndexPath] { get }
-
Returns if the item at a given index path is selected
Declaration
Swift
public final func itemAtIndexPathIsSelected(_ indexPath: IndexPath) -> Bool
Parameters
indexPath
The index path of the item to check
Return Value
True if the item at indexPath is selected
-
Selects all items in the collection view
Note
The delegate will not be notified of the changes
Declaration
Swift
public func selectAllItems(_ animated: Bool = true)
Parameters
animated
If the selections should be animated
-
Select an item at a given index path
Note
The delegate will not be notified of the changes
Declaration
Swift
public func selectItem(at indexPath: IndexPath, animated: Bool, scrollPosition: CollectionViewScrollPosition = .none)
Parameters
indexPath
The indexPath to select
animated
If the selections should be animated
scrollPosition
The position to scroll the selected item to
-
Select the items at the given index paths
Note
The delegate will not be notified of the changes
Declaration
Swift
public func selectItems<C: Collection>(at indexPaths: C, animated: Bool, scrollPosition: CollectionViewScrollPosition = .none) where C.Element == IndexPath
Parameters
indexPaths
The index paths of the items you want to select
animated
If the selections should be animated
-
Deselect cells at given index paths
Note
The delegate will not be notified of the changes
Declaration
Swift
public func deselectItems<C>(at indexPaths: C, animated: Bool) where C : Collection, C.Element == IndexPath
Parameters
indexPaths
The index paths to deselect
animated
If the deselections should be animated
-
Deselect all items in the collection view
Note
The delegate will not be notified of the changes
Declaration
Swift
public func deselectAllItems(_ animated: Bool = false)
Parameters
animated
If the delselections should be animated
-
Deselect the item at a given index path
Note
The delegate will not be notified of the changes
Declaration
Swift
public func deselectItem(at indexPath: IndexPath, animated: Bool)
Parameters
indexPath
The index path for the item to deselect
animated
If the deselection should be animated
-
Returns all visible cells in the collection view
Declaration
Swift
public final var visibleCells: [CollectionViewCell] { get }
-
/ Returns the index paths for all visible cells in the collection view
Declaration
Swift
public final var indexPathsForVisibleItems: [IndexPath] { get }
-
Returns true if the item at the index path is visible
Declaration
Swift
public final func itemAtIndexPathIsVisible(_ indexPath: IndexPath) -> Bool
Parameters
indexPath
The index path of an item in the collection view
Return Value
True if the item is visible
-
Returns the cell at a given index path if it is visible
Declaration
Swift
public final func cellForItem(at indexPath: IndexPath) -> CollectionViewCell?
Parameters
indexPath
An index path of an item in the collection view
Return Value
The cell at the indexpath, or nil if it is not visible
-
Returns the index path for a cell in the collection view
Declaration
Swift
public final func indexPath(for cell: CollectionViewCell) -> IndexPath?
Parameters
cell
A cell in the collection view
Return Value
The index path of the cell, or nill if it is not visible in the collection view
-
Returns a index path for the item at a given point
Declaration
Swift
public func indexPathForItem(at point: CGPoint) -> IndexPath?
Parameters
point
A point within the collection views contentVisibleRect
Return Value
The index path of the item at point, if any
-
Returns the first index path within a given distance of a point
Declaration
Swift
public func firstIndexPathForItem(near point: CGPoint, radius: CGFloat) -> IndexPath?
Parameters
point
A point within the contentDocumentView’s frame
radius
The distance around the point to check
Return Value
The index path for a matching item or nil if no items were found
-
Returns the first index path found intersecting a given rect
Declaration
Swift
public func firstIndexPathForItem(in rect: CGRect) -> IndexPath?
Parameters
rect
A rect within the contentDocumentView’s frame
Return Value
The index path for the matching item or nil if no items were found
-
Returns all items intersecting a given rect
Declaration
Swift
public func indexPathsForItems(in rect: CGRect) -> [IndexPath]
Parameters
rect
A rect within the contentDocumentView’s frame
Return Value
The index paths for all items in the rect. Will be empty if no items were found
-
Returns the indexPath for the section that contains the given point
Declaration
Swift
public final func indexPathForSection(at point: CGPoint) -> IndexPath?
Parameters
point
The point the section must contain
Return Value
The index path for the section contianing the point
-
Returns all visible cells in the collection view
Declaration
Swift
public final var visibleSupplementaryViews: [CollectionReusableView] { get }
-
Returns the index path for a supplementary view
Declaration
Swift
public final func indexPath(forSupplementaryView view: CollectionReusableView) -> IndexPath?
Parameters
view
The supplementary view for which you want the index path
Return Value
The index path for the view
-
Returns the visible supplementary view of the given kind at indexPath
Declaration
Swift
public final func supplementaryViews(forElementKind kind: String, at indexPath: IndexPath) -> CollectionReusableView?
Parameters
kind
The kind of the supplementary view
indexPath
The index path of the supplementary view
Return Value
The view of kind at the given index path
-
Returns the visible supplementary view of the given kind at indexPath
Declaration
Swift
public final func supplementaryView(forElementKind kind: String, at indexPath: IndexPath) -> CollectionReusableView?
Parameters
kind
The kind of the supplementary view
indexPath
The index path of the supplementary view
Return Value
The view of kind at the given index path
-
Scroll an item into view
Declaration
Swift
public func scrollItem(at indexPath: IndexPath, to scrollPosition: CollectionViewScrollPosition, animated: Bool, completion: AnimationCompletion?)
Parameters
indexPath
The index path of the item to scroll to
scrollPosition
The position to scroll the item to within the visible frame
animated
If the scroll should be animated
completion
A closure to call on completion of the scroll
-
Scroll an given rect into view
Declaration
Swift
public func scrollRect(_ aRect: CGRect, to scrollPosition: CollectionViewScrollPosition, animated: Bool, completion: AnimationCompletion?)
Parameters
aRect
The rect within the contentDocumentView to scroll to
scrollPosition
The position to scroll the rect to
animated
If the scroll should be animated
completion
A closure to call on completion of the scroll
-
The index paths for items included in the currect dragging session
Declaration
Swift
public var indexPathsForDraggingItems: [IndexPath] { get }
-
Apply all changes in a change set to a collection view
Declaration
Swift
public func applyChanges(from changeSet: CollectionViewResultsProxy, completion: AnimationCompletion? = nil)
Parameters
changeSet
The change set to apply
completion
A close to call when the update finishes