Layout NSCollectionView with your own NSCollectionViewLayout


First, subclass NSCollectionViewLayout:

class LYExpandableLayout: NSCollectionViewLayout {
}

Tell your collection view to use the layout:

self.collectionView.collectionViewLayout = LYExpandableLayout()

No, it’s not done yet. There are several methods you need to implement in your layout class.

Override collectionViewContentSize and return the calculated content size of the collection view according to the collection items in it.

override var collectionViewContentSize: NSSize {
	
}

Tell if you want to invalidate layout when the bounds change. In most time, just return true here.

override func shouldInvalidateLayoutForBoundsChange(newBounds: NSRect) -> Bool {
    return true
}

Return a selected array of NSCollectionViewLayoutAttributes of item views according to the rect. Ideally, we figure out which item views are in the rect and only return the necessary NSCollectionViewLayoutAttributes of these item views. You can of course return the NSCollectionViewLayoutAttributes of all your item views if the performance won’t be hurt badly by this way.

override func layoutAttributesForElementsInRect(rect: NSRect) -> [NSCollectionViewLayoutAttributes] {
    
}

Here’s the place to calculate the layout attributes. There are several attributes. If you want to control the position, frame should be the one to set. If the items overlaps, you may want to set the zIndex as well.

override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> NSCollectionViewLayoutAttributes? {
    
}

Here’s an example of a customized NSCollectionViewLayout. It layouts a group of fixed sized item views with spacings. When an item is clicked, the following rows of items move downward to make a space. You can fill the space with a view to show detailed information of the item just like the album view in iTunes. download the example project