Search code examples
ios6core-animationuicollectionviewuicollectionviewcell

Animate UICollectionViewCell on Tap


I would like to start some animation on a UICollectionViewCell when the user taps on a cell. My idea was to select the corresponding cell in didSelectItemAtIndexPath and trigger an animation. However, this doesn't work:

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    // animate the cell user tapped on
    ProductCollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ProductReuseID" forIndexPath:indexPath];
    
    [UIView animateWithDuration:5.0
                          delay:0
                        options:(UIViewAnimationOptionAllowUserInteraction)
                     animations:^{
                         NSLog(@"animation start");
                         [cell.layer setBackgroundColor:[UIColor colorWithRed: 180.0/255.0 green: 238.0/255.0 blue:180.0/255.0 alpha: 1.0].CGColor];
                     }
                     completion:^(BOOL finished){
                         NSLog(@"animation end");
                         [cell.layer setBackgroundColor:[UIColor whiteColor].CGColor];
                     }
    ];
}

Actually, the animation starts and ends at the same time (although animateWithDuration is set to 5). Next attempt was to skip the animation and simply set for instance a different border style:

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    // animate the cell user tapped on
    ProductCollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ProductReuseID" forIndexPath:indexPath];
    
    [cell.layer setBorderWidth:5.0f];
}

However, this doesn't change anything (probably because I have to redraw the cell manually?).

Do you have any ideas how to animate a UICollectionViewCell when the user tapped on it?

Kind regards, Christian


Solution

  • It would appear that you are obtaining the wrong Cell. Sending the dequeueReusableCellWithReuseIdentifier:forIndexPath: message does not obtain the cell in use in the view at the indexPath in the second parameter, but dequeues a previously used but reusable cell; if no reusable cell is available, a new one is created. See Reference 1 below.

    Replacing:

    ProductCollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ProductReuseID" forIndexPath:indexPath];
    

    With:

    ProductCollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
    

    In your code above, should give you the proper cell to work with.

    Here is your fist example, rewritten.

    - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath(NSIndexPath *)indexPath
    {
        // animate the cell user tapped on
        UICollectionViewCell  *cell = [collectionView cellForItemAtIndexPath:indexPath];    
        [UIView animateWithDuration:5.0
                delay:0
                options:(UIViewAnimationOptionAllowUserInteraction)
                    animations:^{
                        NSLog(@"animation start");
                        [cell setBackgroundColor:[UIColor colorWithRed: 180.0/255.0 green: 238.0/255.0 blue:180.0/255.0 alpha: 1.0]];
                    }
                    completion:^(BOOL finished){
                        NSLog(@"animation end");
                        [cell setBackgroundColor:[UIColor whiteColor]];
                    }
        ];
    }
    

    References: