BenRB
BenRB

Reputation: 330

UICollectionView displays cells incorrectly after frame change

I noticed that if I change the frame of a UICollectionView (e.g. when the toggling the in-call status bar), the collection view doesn't update its cells properly for its new frame. It's probably easiest to see in a short video:

http://cl.ly/2t2Y2A3A2w1D/CollectionViewTest.mov

The source files for that simple test are here:

http://cl.ly/0S0A360B3I3Q/CollectionViewTest.zip

It doesn't seem to matter whether I use UICollectionViewController or UIViewController. Has anyone seen this? Am I missing something? The only workaround I've found is to call reloadData on the collection view in the view controller's viewWillLayoutSubviews or viewDidLayoutSubviews which works but is far from ideal when the collection view's frame is being affected by a user drag since reloadData is called many times and results in very sluggish UI updates while the user is dragging.

Upvotes: 7

Views: 12165

Answers (3)

marmor
marmor

Reputation: 28179

I had a similar problem, where my UICollectionView's frame changed and unless I call reloadData it got stuck in the same spot without moving with the CollectionView.

I've fixed it by adding this to my CollectionViewFlowLayout:

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}

Worked nicely.

Upvotes: 10

Dcritelli
Dcritelli

Reputation: 820

I had a similar problem. I just needed to resize the collection view frame so that a menu could show below it and the user could still scroll up far enough that the menu doesn't cover the cells at the bottom.

Changing the content inset worked for me.

self.collectionView.contentInset = UIEdgeInsetsMake(0, 0, rect.size.height+8, 0);

I couldn't get changing the frame of the collection view to work without reloading the data, which would screw up cells that were already selected by the user.

Upvotes: 2

rdelmar
rdelmar

Reputation: 104082

You can have your UICollectionViewController register for the UIApplicationWillChangeStatusBarFrameNotification, and reloadData in the selector. That way, you'll only be reloading the data when the status bar changes frame.

- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callCameIn:) name:UIApplicationWillChangeStatusBarFrameNotification object:nil];
}

-(void)callCameIn:(NSNotification *) aNote {
    [self.collectionView reloadData];
}

Upvotes: 0

Related Questions