Marc Marc - 1 month ago 30
Objective-C Question

UICollectionVIew: Animate cells as they scroll in

I would like items in my

UICollectionView
to animate in to view as the user scrolls through the list (I am using a subclass of
UICollectionViewFlowLayout
).

I specify the position in the Layout Manager, what I would like to be able to do is to also specify an initial transform and have that applied in an animation at the correct time (when the cell first appears on screen). To see the effect I mean, check out the Google Plus app on iOS. Ideally a different transform depending on the location of the cell.

I can't seem to find a way to find out when a cell is displayed (no equivalent of
willDisplayCell
as there is on
UITableView
) or any pointers on where to go for this.

Any suggestions?

You can just about make out the animation in Google Plus in this screen shot:
Example in the Google Plus App

Also, take a look at iPhoto on the iPad. I don't know if they're using a UIcollectionView (probably not, as it worked on iOS5) but this is the sort if effect I'm looking for, the photos appear to fly in from the right.

Answer

You can achieve this effect independently of having a custom layout.

The animation code should go inside collectionView:cellForItemAtIndexPath:

When a cell is dequeued, its frame will be set to what is specified in your layout. You can store it in a temporary variable as the final frame for the cell. You can then set the cell.frame to a initial position outside the screen, and then animate towards the desired final position. Something along the lines of:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    UICollectionView *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];

    CGRect finalCellFrame = cell.frame;
    //check the scrolling direction to verify from which side of the screen the cell should come.
    CGPoint translation = [collectionView.panGestureRecognizer translationInView:collectionView.superview];
    if (translation.x > 0) {
        cell.frame = CGRectMake(finalCellFrame.origin.x - 1000, - 500.0f, 0, 0);
    } else {
        cell.frame = CGRectMake(finalCellFrame.origin.x + 1000, - 500.0f, 0, 0);
    }

    [UIView animateWithDuration:0.5f animations:^(void){
        cell.frame = finalCellFrame;
    }];

    return cell;
}

The code above will animate cells on a horizontal UICollectionView, coming from the top of the screen, and from either side, depending on the scrolling direction. You could also check the current indexPath to have cells animating from different positions on more complicated layouts, as well as animate other properties along with the frame, or apply a transform.