MLQ
MLQ

Reputation: 13511

scrollToItemAtIndexPath destroys UICollectionViewCell layout

I am creating a paginated UICollectionView that scrolls horizontally and whose cells are as big as the collection view so that only one cell is shown at a time. I also want to display the last item first when the collection view first appears, so that the other items are revealed from the left instead of the default where the next items come in from the right.

To do that, I call scrollToItemAtIndexPath: in my view controller's viewDidLayoutSubviews as suggested by this answer. If I put the call to scrollToItemAtIndexPath in viewWillAppear or viewDidLoad, the collection view does not at all scroll to the last item.

However, this call destroys the layout of my collection view cells. For example, if I don't call scrollToItemAtIndexPath:, the collection view (the white area below) looks like the left one--correctly laid out but showing the first item. If I call scrollToItemAtIndexPath:, the collection view does initially display the last item, but the layout is messed up like in the right (the date isn't even showing anymore).

enter image description here

What am I doing wrong?

More info:

The code for viewDidLayoutSubviews:

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    NSIndexPath *lastIndexPath = [NSIndexPath indexPathForItem:self.unit.readings.count - 1 inSection:0];
    [self.readingCollectionView scrollToItemAtIndexPath:lastIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
}

Upvotes: 2

Views: 1776

Answers (2)

MLQ
MLQ

Reputation: 13511

I put the following in viewWillLayoutSubviews (also works in viewDidLayoutSubviews):

[self.readingCollectionView scrollToItemAtIndexPath:lastIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
[self.readingCollectionView reloadData];

A UI issue persists, however: when the view controller appears, it displays the first item, THEN immediately refreshes to display the last item instead.

To get around this seemingly unresolvable problem, I hacked the UI instead: display a "Loading" label before the view controller appears, and show the collection view in viewDidAppear.

Upvotes: 2

Paul.s
Paul.s

Reputation: 38728

Whenever I've had this issue and I have a constant size cell I've worked around it by just setting the contentOffset manually and ignoring the collectionView methods.

self.collectionView.contentOffset = (CGPoint){
  .x = self.collectionView.contentSize.width - cell.width,
  .y = 0,
};

Upvotes: 2

Related Questions