the_critic
the_critic

Reputation: 12820

Collection View, Auto layout UICollectionViewFlowLayout and itemSize

I am really struggling to achieve something fairly simple: I would like to create a horizontal collection view where the UICollectionViewCells are the size of the UICollectionView itself.

So far so good, I have set up a view controller in the storyboard which looks something like this (notice: collection view is not equal to view controller's size):

+--------------------------+
|                          |
|         Some View        |
+--------------------------+ <----- constraint
|                          |
|                          |
|      Collection View     | <----- left and right constraint
|                          |
|                          |
+--------------------------+ <----- constraint
|                          |
|      Some other view     |
+--------------------------+

Issue:

The collection view's cells do not seem to be the size of the collection view, despite explicitly setting the itemSize property of the collection view's flow layout property to the collection view's frame's size in the viewDidLoad() method of the controller.

In viewDidLoad() I do something like this:

let layout = self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = self.collectionView.frame.size
layout.headerReferenceSize = CGSizeZero
layout.footerReferenceSize = CGSizeZero
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0

The strange thing:

When I put this code into awakeFromNib(), it seems as if the collectionView is not hooked up -> crash. However, when I put the code into viewDidAppear(), the collection view shortly appears with wrongly sized cells (whatever is set in the storyboard) and shortly after, the cells update to the correct size.

Can anybody help me with this issue ?

EDIT:

Also seems to work in viewDidLayoutSubviews(). Not sure why, but I guess it is because the constraints have not been applied in viewDidLoad() yet.

Upvotes: 3

Views: 1980

Answers (2)

Wouter
Wouter

Reputation: 146

You might wanna try the following: In the ViewController, implement the didLayoutSubviews() function as follows:

override func didLayoutSubviews() {
    super.didLayoutSubviews()
    let collectionViewSize = self.collectionView.bounds.size
    if let flowLayout = self.collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
        flowLayout.itemSize = collectionViewSize
    }
}

Upvotes: 0

Mykola Denysyuk
Mykola Denysyuk

Reputation: 1985

If collectionView's cells must have static size you should set it in Interface Builder's Utilities bar, here:

enter image description here

Otherwise, implement UICollectionViewDelegateFlowLayout protocol's collectionView(_:layout:sizeForItemAtIndexPath:) method in your delegate controller and return from there desired cell's size.

Upvotes: 1

Related Questions