Messing around with NSCollectionViewItem

Harry Ng
macOS App Development
3 min readAug 8, 2016

Are you Mac App Developer? Did you use the latest NSCollectionView with APIs updated in 2015? If you have used this, you probably faced the same issues I had. Let’s take a look.

Storyboard does not set properly

I like to use Storyboard. To use NSCollectionView, my natural first step was to drag the view into the Storyboard. It looks like the following.

NSCollectionViewItem comes with NSCollectionView

If I try to run the project at this point, an error will show up.

Unknown segue???

I ended up searching and searching, many people faced this before. It happened since 2014, which is before the massive API update. There is no solution so far, but to delete it.

Overriding content size is not easy

I come from iOS development background, and have been using UICollectionView. One common trick is to change the contentSize so that I get a bigger scrollable region. This is useful to set offset to a certain area for display.

Unlike UICollectionView, there is no ‘contentSize’ property in NSCollectionView. Instead, one may change the contentSize using the property from NSCollectionViewLayout, namely ‘collectionViewContentSize’. This exists in the counterpart of iOS as well. This also means, it’s the time to use the new API available in 2015 update.

Then I shall create a subclass of NSCollectionViewFlowLayout, assuming I prefer flow layout. I can now override the property to allow a bigger content size. As I am replacing the layout, I shall set the item size in code as well.

Creating placeholder of the item may cause issues

Each item has a size. Sometimes, instead of making item using data source, I would want to create the item as a placeholder. This is to perform some size calculation based on the content of the item.

If I simply create the item, the UI components inside are not linked. In general, we connect those component from the object. When NSCollectionView makes the item, it will link them up properly.

However, if I initialize the item using constructor, those components are not connected. Sometimes, I would even get the error of ‘view not loaded’. There are two parts to the solution.

Part 1: In order to make sure the NSView is available in creation, you should connect the view to both File’s Owner and the Object. In this case, we will rely on the File’s Owner connection to initialize the view.

Part 2: For other UI components, they serve as subviews in Interface Builder. We need to connect them manually. Simply loop through all the subviews and match them with pre-defined identifiers.

I have created this sample project that solves all these problems, you can find out the source code here.

--

--