hpique
hpique

Reputation: 120354

Animating UICollectionView on orientation changes

Consider a UICollectionView that has a different number of items and a different layout (ie: spacing) on landscape and portrait orientation.

What needs to be done for these changes to be animated when the device is rotated? I couldn't find any mention of how to handle rotations on the Collection View Programming Guide.

Upvotes: 15

Views: 17053

Answers (5)

Antoine
Antoine

Reputation: 23996

I used the following simple code in Swift:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
    collectionView.collectionViewLayout.invalidateLayout()
}

Upvotes: 3

CZ54
CZ54

Reputation: 5586

The quickest way is a mix of all other answers.

just add the following lines in your ViewController :

override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
    self.mCollectionView.collectionViewLayout.invalidateLayout()
}

You do not need to reloadData.

Upvotes: 6

Juanma Reyes
Juanma Reyes

Reputation: 21

I am using this approach if you only want to do something at a rotation event:

- (void)updateViewConstraints {
    [super updateViewConstraints];
    [[_cvMyCollectionView collectionViewLayout] invalidateLayout];
}

and then override the method from UICollectionViewDelegateFlowLayout

    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
        /* 
         * Calculate size, example
         * */
         CGSize cellSize = CGSizeMake(150.0f, 150.0f);

      return cellSize;
      }

with the desired behaviour in landscape and portrait or depending on the width for example.

You can even save previous orientation and check if it changed to decide whether to invalidate layout or not.

This will refresh sizes even when you come back again in a navigation controller.

Upvotes: 0

titaniumdecoy
titaniumdecoy

Reputation: 19251

It's not necessary to reload the collection view's data — invoking [collectionView.collectionViewLayout invalidateLayout] will cause the collection view to update its layout.

Overriding shouldInvalidateLayoutForBoundsChange: to return YES in a UICollectionViewLayout subclass will result in invalidateLayout being called automatically whenever the collection view's bounds change (including when its size changes and when the user scrolls its contents).

Upvotes: 40

christophercotton
christophercotton

Reputation: 5879

I had different number of sections based on the orientation, and the auto rotation didn't change it. I had to add a call to the collectionView to reload the data. I'm using a UICollectionViewController, adjust to your own collection view property if you have something else:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(    NSTimeInterval)duration {
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [self.collectionView reloadData];
}

Upvotes: 13

Related Questions