Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animating all UICollectionViewCells in a UICollectionView

I was wondering what a good way to animate all the cells in a UICollectionView is. I'm trying to simulate editing in a UICollectionView. So what I want to do is shrink all the bounds of the UICollectionViewCells. So what I have is this:

- (IBAction)startEditingMode:(id)sender {
    [_items enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:idx inSection:0];
        UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];

        [UIView animateWithDuration:0.25 animations:^{
            cell.layer.transform = CATransform3DMakeScale(0.9, 0.9, 1);
        }];
    }];
}

It works, but I wasn't sure if there was a property on UICollectionView, or a better more standard way to do something like this. Thanks.

like image 652
Crystal Avatar asked Nov 13 '22 16:11

Crystal


1 Answers

I would create a UICollectionViewLayout subclass. Add a BOOL property called editing. When editing changes, call invalidateLayout. Then in the attribute returned by the -layoutAttributesForItemAtIndexPath: method you can specify a transform.

The problem with your approach is that it affects only the visible cells. The UICollectionViewLayout subclass is nice because it will apply the transform to all of the cells even as new ones get added. And it moves all of the collection view layout handling out of the view controller.

Cell attributes can include frame, size, center, transform(3D), alpha, and your own custom attributes.

You'll change the value of editing in a -performBatchUpdates: block, as suggested by wL_.

- (IBAction)startEditingMode:(id)sender {
    [self.collectionView performBatchUpdates:^{
        ((MyCollectionViewLayout *)self.collectionView.collectionViewLayout).editing = YES;
    }
    completion:NULL];
}

And in the UICollectionViewLayout subclass:

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

    if (self.editing) {
        attributes.transform = CGAffineTransformMakeScale(0.9, 0.9);
    }
    else {
        attributes.transform = CGAffineTransformIdentity;
    }

    return attributes;
}

Also note you (probably) don't need a 3D transform here. An affine transform is sufficient.

like image 90
Dave Batton Avatar answered Nov 15 '22 07:11

Dave Batton