Auto Layout size of CollectionViewCell in relation to CollectionView

1.5k views Asked by At

I have a CollectionViewCell placed in a CollectionView. The size of the CollectionView is set via Auto Layout and can change at times.

I want to (programmatically) set constraints on my CollectionView, so that the size of the CollectionViewCell is responsive to the size of the CollectionView (Say the width of the Cell is equal to the width of the CollectionView-100 and the height should be equal).

How can I declare constraints between the Cell and the CollectionView?

When, where and how do set those constraints? Do I have to call setNeedsLayout on the Cells when the size of the CollectionView changes?

I searched for this quite long and all I found was always about changing the size of the Cell according to its content – that’s not what I am trying to do. The only hint that I got is that I might have to subclass CollectionViewLayout – but I’m not sure about that.

Any help is appreciated!

3

There are 3 answers

4
Zell B. On BEST ANSWER

You cannot achieve this using constraints, but you can easily do this using UICollectionViewDelegate's sizeForItemAtIndexPath method. Example:

func collectionView(collectionView: UICollectionView, 
       layout collectionViewLayout: UICollectionViewLayout,
  sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    return CGSize(width: collectionView.frame.size.width / 2, height: collectionView.frame.size.height/ 2)
}

And after changing the collectionView size all you need to do is call its reloadData method.

0
David On

I can suggest for you 2 ways how to do this:

  1. In your UIViewController try to set the collectionViewLayout property in viewDidLayoutSubviews method. I'm not sure if it works when screen orientation will change.
- (void)viewDidLayoutSubviews
{
  UICollectionViewFlowLayout *flow  = YOUR_COLLECTION_VIEW.collectionViewLayout;
  float width = CGRectGetWidth(YOUR_COLLECTION_VIEW.frame)-100.f;
  float height = CGRectGetHeight(YOUR_COLLECTION_VIEW.frame);
  YOUR_COLLECTION_VIEW.collectionViewLayout = flow;
}
  1. If that doesn't work, then I'm 100% sure that it will work if you subclass the collectionView and insert the same code but in (void)layoutSubviews
0
craft On

Set the cell height and get the collection view height in UICollectionViewDelegateFlowLayout sizeForItemAt method. You can set the cell size based on a whole number or multiply as a percentage if that's more appropriate.

func collectionView(_ collectionView: UICollectionView, layout 
collectionViewLayout: UICollectionViewLayout, sizeForItemAt 
indexPath: IndexPath) -> CGSize {
        let heigh = collectionView.frame.height
        let widthOfCell = collectionView.frame.width - 100 // OP request
        return CGSize(width: width, height: height) 
}