Search code examples
iosobjective-ciphoneuicollectionviewnsindexpath

ios - going from an integer (int or NSInteger) to an NSIndexPath* for a UICollectionView


I'm trying to call collectionView...scrollToItemAtIndexPath to scroll my UICollectionView to the ith cell, where i is the index of the element. My collection view has only one section, and when I go the other away around, I always call dataArray[indexPath.item] to get the data for the element at indexPath. However, I'm having trouble getting an indexPath from an integer.

[NSIndexPath indexPathForRow:] works only for UITableView

[NSIndexPath indexPathWithIndex:] doesn't return an NSIndexPath with a section

[NSIndexPath indexPathForItem:inSection:0] returns a path of 0 length that, when used to get the cell with [collectionView cellAtIndexPath:] returns nil.

Any idea what I can do to get a valid index path that I can then use to scroll my UICollectionView? Assume that I have only the NSInteger index of the data array. Thanks.

UPDATED WITH CODE:

NSIndexPath* pathToCell = [NSIndexPath indexPathForItem:curIndex inSection:0];
    CustomCollectionViewCell* updatedCell = (CustomCollectionViewCell*)[self collectionView:self.collection cellForItemAtIndexPath:pathToCell];
    selectedContent = updatedCell.cellContentView;

    // scroll to cell and recenter cover on it
    [self.collection scrollToItemAtIndexPath:pathToCell atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];

Then I use the location of the cell to recenter a "cover" view on top of it:

// Animate
CGPoint coverCenter = [childView convertPoint:selectedContent.center toView:parentView];

coverSelectDummy.center = coverCenter;
coverSelectDummy.imageView.image = selectedContent.imageView.image;
coverSelectDummy.imageLabel.text = selectedContent.imageLabel.text;
coverSelectDummy.alpha = 1.0;
coverSelectDummy.transform = CGAffineTransformIdentity;
coverSelectDummy.hidden = NO;

[self.view bringSubviewToFront:coverSelectDummy];

[UIView transitionWithView:coverSelectDummy duration:0.1f options: UIViewAnimationOptionCurveLinear animations:^(void)
 {
     coverSelectDummy.alpha = 1.0;
     coverSelectDummy.transform = CGAffineTransformMakeScale(1.2, 1.2);

 }
                completion:^(BOOL finished)
 {
     // .... processing ....
 }];

Solution

  • cellForItemAtIndexPath: returns nil if the cell isn't visible (documentation). So if you want to scroll to an item that isn't currently on-screen, that won't work. If I understand correctly you just want to scroll somewhere, so I don't think you even need to worry about that method anyway.

    You should be creating an NSIndexPath object using indexPathForItem:inSection:, and then scroll to that index path using the scrollToItemAtIndexPath:atScrollPosition:animated:

    So, assuming the collection view is a property of the View Controller in question and you have a scroll position variable in play:

    NSInteger itemToScrollTo = 10;
    NSIndexPath *indexPathToScrollTo = [NSIndexPath indexPathForItem:itemToScrollTo inSection:0];
    [self.collectionView scrollToItemAtIndexPath:indexPathToScrollTo atScrollPosition:scrollPosition animated:YES];