Note that there are some explanatory texts on larger screens.

plurals
  1. PODynamically setting layout on UICollectionView causes inexplicable contentOffset change
    primarykey
    data
    text
    <p>According to Apple's documentation (and touted at WWDC 2012), it is possible to set the layout on <code>UICollectionView</code> dynamically and even animate the changes:</p> <blockquote> <p>You normally specify a layout object when creating a collection view but you can also change the layout of a collection view dynamically. The layout object is stored in the collectionViewLayout property. Setting this property directly updates the layout immediately, without animating the changes. If you want to animate the changes, you must call the setCollectionViewLayout:animated: method instead.</p> </blockquote> <p>However, in practice, I've found that <code>UICollectionView</code> makes inexplicable and even invalid changes to the <code>contentOffset</code>, causing cells to move incorrectly, making the feature virtually unusable. To illustrate the problem, I put together the following sample code that can be attached to a default collection view controller dropped into a storyboard:</p> <pre><code>#import &lt;UIKit/UIKit.h&gt; @interface MyCollectionViewController : UICollectionViewController @end @implementation MyCollectionViewController - (void)viewDidLoad { [super viewDidLoad]; [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"CELL"]; self.collectionView.collectionViewLayout = [[UICollectionViewFlowLayout alloc] init]; } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return 1; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"CELL" forIndexPath:indexPath]; cell.backgroundColor = [UIColor whiteColor]; return cell; } - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"contentOffset=(%f, %f)", self.collectionView.contentOffset.x, self.collectionView.contentOffset.y); [self.collectionView setCollectionViewLayout:[[UICollectionViewFlowLayout alloc] init] animated:YES]; NSLog(@"contentOffset=(%f, %f)", self.collectionView.contentOffset.x, self.collectionView.contentOffset.y); } @end </code></pre> <p>The controller sets a default <code>UICollectionViewFlowLayout</code> in <code>viewDidLoad</code> and displays a single cell on-screen. When the cells is selected, the controller creates another default <code>UICollectionViewFlowLayout</code> and sets it on the collection view with the <code>animated:YES</code> flag. The expected behavior is that the cell does not move. The actual behavior, however, is that the cell scroll off-screen, at which point it is not even possible to scroll the cell back on-screen.</p> <p>Looking at the console log reveals that the contentOffset has inexplicably changed (in my project, from (0, 0) to (0, 205)). I posted a solution for the <a href="https://stackoverflow.com/questions/13716825/setting-a-new-collectionviewlayout-for-uicollectionview-giving-blank-screen/13775364#13775364">solution for the non-animated case</a> (<code>i.e. animated:NO</code>), but since I need animation, I'm very interested to know if anyone has a solution or workaround for the animated case.</p> <p>As a side-note, I've tested custom layouts and get the same behavior.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload