6

I want to have a UICollectionView that scrolls from right to left, i.e. when it appears on screen after being loaded the collection view should should show the rightmost cells/items first and then add the rest at the left. I've tried the workaround presented here however if I call this in viewWillAppear: I get:

*** Assertion failure in -[UICollectionViewData layoutAttributesForItemAtIndexPath:], /SourceCache/UIKit/UIKit-2372/UICollectionViewData.m:485

If I scroll to the last item in viewDidAppear: it works fine, except now user first sees the left items and then the scrolling to the last item. Also tried using the contentOffset property on UICollectionView (as it's a subclass of UIScrollView) but this parameter is also only set sometime in-between viewWillAppear: and viewDidAppear:

Any alternatives? I guess I could try subclassing the UICollectionViewFlowLayout and layout the cells from right to left, but I'm a little anxious to go into that territory.

This is what I do:

- (void)_scrollToTheRight
{
    NSIndexPath *lastIndexPath = [self.fetchedResultsController indexPathForObject:self.fetchedResultsController.fetchedObjects.lastObject];
    if (lastIndexPath)
    {
        [self.collectionView scrollToItemAtIndexPath:lastIndexPath atScrollPosition:UICollectionViewScrollPositionRight animated:NO];
    }
}

Each value is:

lastIndexPath
(NSIndexPath *) $0 = 0x1f1754a0 <NSIndexPath 0x1f1754a0> 2 indexes [0, 21]

(NSInteger)[self.fetchedResultsController.fetchedObjects count]
(NSInteger) $3 = 22 [no Objective-C description available]

(NSInteger)[self.collectionView numberOfItemsInSection:0]
(NSInteger) $2 = 22 [no Objective-C description available]

Last note: the collection view controller is loaded from a container view (new in iOS 6 storyboards) of a view controller that is put on screen by a UIPageViewController.

Thanks.

EDIT 1: So I think the problem is that using my storyboard layout (UICollectionViewController's embedded using the new Container Views) is causing the problem. enter image description here Because elsewhere in the app where I also embed view controllers (a normal UITableViewController) viewDidAppear: gets called before the view actually appears. I'm suspecting that this setup is not notifying each child view controller properly that they should load and layout their views.

Community
  • 1
  • 1
ChrHansen
  • 1,502
  • 1
  • 14
  • 22
  • In the test project I made for the answer I provided in your link, I had scrollToItemAtIndexPath: method in viewDidLoad (after creating the collection view). I don't know if that will make a difference. – rdelmar Dec 19 '12 at 18:45
  • Thanks, I think the issue is not with the collection view, but the relationship between parent and child viewcontrollers (see my EDIT 1). – ChrHansen Dec 20 '12 at 18:09
  • I tried moving my collection view project into a container view, and it worked fine if I put the code in the viewDidAppear:animated: method. I had the definition of the array, the collection view, and the scroll to end code all in that method. – rdelmar Dec 20 '12 at 20:39

1 Answers1

3

Since iOS 9 one can use

collectionView.semanticContentAttribute = .forceRightToLeft

for right to left scrolling when scrollDirection = .horizontal and the itemSize fills the entire height (i.e. only one horizontal line of items)

bbjay
  • 1,728
  • 3
  • 19
  • 35
  • 1
    Sidenote: For this solution to work correctly, you need to reverse the sort order in the data source to see the expected results. – Hans Bondoka Apr 13 '21 at 09:12