Idr
Idr

Reputation: 6250

Collection View does not update layout at Rotation

This is the view of the app when it is in portrait mode. enter image description here

When it is rotated to landscape mode it looks like this

enter image description here

The view debugger shows that the UIWindow is not rotating as shown here enter image description here

The UICollectionViewController is created via StoryBoard. I've tried subclassing UICollectionViewFlowLayout that implements shouldInvalidateLayoutForBoundsChange, but it does not fix my issue.

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
    CGRect oldBounds = self.collectionView.bounds;
    if (CGRectGetWidth(newBounds) != CGRectGetWidth(oldBounds)) {
        return YES;
    }
    return NO;
}

Please provide ideas of what to check next or requests for additional code to debug.

Edit - As suggested by MirekE, I attempted to add constraints to the CollectionView but was unable. All of the options for Editor->Pin are unavailable for the CollectionView. enter image description here

Edit, response to Andrea -

I'm targeting iOS8.3. My understanding is that the main method called at rotation is viewWillTransitionToSize:withTransitionCoordinator:, which is from the UIContentContainer protocol. I've added the following to my CollectionViewController, but same problem persists

-(void)viewWillTransitionToSize:(CGSize)size
      withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator {
    [self.collectionView.collectionViewLayout invalidateLayout];
    [self.collectionView reloadData];
}

Upvotes: 7

Views: 7642

Answers (4)

Andrea
Andrea

Reputation: 26385

I don't know which iOS version you ara targeting, but let me suppose that you know the rotation process and methods called in the view controller while it's happening.
In one of those methods you just need to call:

[self.collectionView.collectionViewLayout invalidateLayout];

and maybe depending on your layout -reloadData
No need to subclass.


EDIT

I use this method, I guess that is not working because you should relayout the collection after it has resized:

- (void) willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator];


    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
        [self.collectionView.collectionViewLayout invalidateLayout];            
    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
        [self.collectionView reloadData];
    }];

}


What I'm doing attach the layout invalidation process to the animation process.

Upvotes: 12

Alex V
Alex V

Reputation: 51

If you have custom implementation of UICollectionViewLayout, try to override methods:

override public func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
    let bounds = self.collectionView!.bounds;
    return ((CGRectGetWidth(newBounds) != CGRectGetWidth(bounds) ||
        (CGRectGetHeight(newBounds) != CGRectGetHeight(bounds))));
}

override public func invalidateLayout() {
    cache.removeAll()  // remove layout attributes ans settings if they exist
    super.invalidateLayout()

}

Cheers !

Upvotes: 5

Idr
Idr

Reputation: 6250

The problem was that the collectionView outlet was not properly set. After setting the collectionView, all works properly.

collectionView outlet not set:

enter image description here

collectionView outlet set:

enter image description here

Upvotes: 1

MirekE
MirekE

Reputation: 11555

It looks like you just drag the collection view on the canvas, but did not add any constraints. So when you rotate the device, the size does not change.

In the storyboard select the collection view, then click on the Pin icon at the bottom of Xcode and add constraints for the top, left, bottom and right margins. After you do that, the collection view should resize on rotation.

Upvotes: 1

Related Questions