Search code examples
iosautolayoutuicollectionviewuicollectionviewcellsize-classes

UICollectionViewCell - different layout for different size classes


I have a simple UICollectionViewCell with one image and a label. In regular-regular size class I want the image to be on top, and the label below it. This is what it looks like in the Xcode's preview tab:

enter image description here

In any other size class I want the image to be on the left, and the label on the right:

enter image description here

I setup the constraints this way:

ImageView has following constraints:

  • leading and top constraints for Any-Any
  • fixed width and height for Any-Any

The label has following constraints:

  • trailing constraint to Superview - for Any-Any
  • top constraint to the ImageView - only for Regular-Regular
  • leading constraint to Superview - only for Regular-Regular
  • top constraint to Superview - for Any-Any but not for Regular-Regular
  • leading constraint to ImageView - for Any-Any but not for Regular-Regular

I also implemented the method to return the different cell size based on the current trait collection:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    if (traitCollection.horizontalSizeClass == .Regular) {
      return CGSizeMake(240, 194)
    }
    else {
      return CGSizeMake(340, 128)
    }
  }

The cell looks fine in the preview, and everything works fine when I run it on iPhone (e.g Compact-Regular). However, auto layout breaks when I run it on iPad:

enter image description here

And of course I get a bunch of warnings in the debug console: Unable to simultaneously satisfy constraints.

So, I guess the question is - what is the proper way of setting up the cell for different size classes?

I created a github repo with a demo project

Thanks!


Solution

  • What you want to do is disable those constraints for the Regular-Regular size class like you have, but also change their priority to < 1000 (i.e. not required). That way it will instead use the higher priority constraints for the specific size class.

    enter image description here