iosuicollectionviewsize-classesadaptive-layout

Change cell layout when traitCollection changes


I'm having problems adjusting a cell's layout when the horizontal size class changes.

My cell has a stackView and I want the axis to be Horizontal for Compact size class and Vertical for Regular.

This is what I tried:

override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
    if previousTraitCollection?.horizontalSizeClass != traitCollection.horizontalSizeClass {
        self.collectionView?.reloadData()
    }
}

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! MyCollectionViewCell

    switch traitCollection.horizontalSizeClass {
    case .Compact:
        cell.stackView.axis = .Horizontal
    default:
        cell.stackView.axis = .Vertical
    }

    return cell
}

But the result is that not all cells update their layout, se the gif below.

EDIT: I have confirmed that the axis is changed correctly by printing in cellForItem and in the cell class itself. So the issue seems to be that the cells are not redrawn..

Cell layout problems

Any suggestions how i should solve this?

Github Repo


Solution

  • Add a call to layoutIfNeeded() to the cellForItemAtIndexPath method in order to get the stack view to relayout its contents:

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! MyCollectionViewCell
    
        switch traitCollection.horizontalSizeClass {
        case .Compact:
            cell.stackView.axis = .Horizontal
        default:
            cell.stackView.axis = .Vertical
        }
    
        cell.stackView.layoutIfNeeded()
    
        return cell
    }