Kevvv
Kevvv

Reputation: 4023

How to use a UICollectionViewController's custom initializer with UICollectionViewCompositionalLayout?

Let's say you wanted to use a custom initializer to instantiate UICollectionViewController.

With UICollectionViewFlowLayout, it's straightforward:

init() {
    let layout = UICollectionViewFlowLayout()
    super.init(collectionViewLayout: layout)
}

But, UICollectionViewCompositionalLayout's designated initializers require a few parameters, most importantly the section parameter:

UICollectionViewCompositionalLayout(section:, configuration:)
// or 
UICollectionViewCompositionalLayout(sectionProvider:, configuration:)

This means I have to create the entire layout within the custom initializer of UICollectionViewController. If the layout incorporates things like enum as a section identifier, that has to be in the initializer as well. If you have to include NSCollectionLayoutEnvironment in your layout, it also becomes problematic.

init() {
    let item = /..
    let group = /..
    let section = /..
    let layout = UICollectionViewCompositionalLayout(section: section)
    super.init(collectionViewLayout: layout)
}

I'm looking at the Apple's examples and all of them use UIViewController instead of UICollectionViewController by default. Even though the examples don't use any custom initializers, this method does get around the aforementioned problem by allowing us to create the layout afterwards:

var collectionView: UICollectionView! = nil
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createLayout())

You can now simply use the UIViewController's custom initializer.

What is the best way to use UICollectionViewCompositionalLayout with a custom initializer?

Upvotes: 0

Views: 874

Answers (1)

matt
matt

Reputation: 535756

You may be over-thinking this. There is absolutely no law preventing you from changing the layout assigned to a collection view; its collectionViewLayout property is assignable at any time.

So just assign a "dummy" layout to the collection view controller in the initializer, and then do the real creation and assignment of the layout in viewDidLoad just as you normally would.

Just to give a common use case: how would you create a collection view controller in the storyboard if you wanted to use a compositional layout? What I do is give the collection view in the storyboard a flow layout. Then in viewDidLoad I create the real layout (the compositional layout) in code and assign it to self.collectionView.collectionViewLayout, and no harm done.

Upvotes: 2

Related Questions