2

I am trying to figure out a way to animate the deletion of a UICollectionViewCell similarly to springboard in iOS 7. The deleted cell should shrink into nothingness and the remaining cells should slide over to fill its place (the sliding is the important part). I have tried:

• Setting the frame of each cell to the frame of the previous cell, like so:

UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
CGRect rect = [self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:i - 1 inSection:0]].frame;      
[UIView animateWithDuration:0.2 animations:^{
    cell.frame = rect;
}];

But this did not work, as the cells did not move at all.

• Both of the following:

[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:nil];

and

[UIView animateWithDuration:0.2 animations:^{
    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
}];

But these make the cells crossfade to their required spots, not slide.

I also found this project, which uses the following:

for (int i = index+1; i<[items count]; i++) {
    SEMenuItem *item = [items objectAtIndex:i];
    [UIView animateWithDuration:0.2 animations:^{

        if (i < index + remainingNumberOfItemsInPage) {

            int intVal = item.frame.origin.x;
            if (intVal %3== 0)
                [item setFrame:CGRectMake(item.frame.origin.x+2*item.frame.size.width, item.frame.origin.y-item.frame.size.height-5, item.frame.size.width, item.frame.size.height)];
            else
                [item setFrame:CGRectMake(item.frame.origin.x-item.frame.size.width, item.frame.origin.y, item.frame.size.width, item.frame.size.height)];
        }

        [item updateTag:item.tag-1];
    }];
}

However, it is not in a UICollectionView, so it does not help me.

Note: I am doing this on an iPad, just in case it matters to you.

Any ideas?

ricky3350
  • 1,710
  • 3
  • 20
  • 35
  • I wish I could post a full answer, because I've done something like this. Just set the size of the cell to `CGSizeZero` and it's origin to the point previously the `center` of the cell in the following method https://developer.apple.com/library/ios/documentation/uikit/reference/UICollectionViewLayout_class/Reference/Reference.html#//apple_ref/occ/instm/UICollectionViewLayout/finalLayoutAttributesForDisappearingItemAtIndexPath: – duci9y Jul 19 '14 at 21:38

2 Answers2

1

Subclass UICollectionViewFlowLayout. Implement:

- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewLayoutAttributes *attr = [self layoutAttributesForItemAtIndexPath:indexPath]; // might need to replace self with super

    attr.transform = CGAffineTransformMakeScale(0, 0);

    return attr;
}
duci9y
  • 4,128
  • 3
  • 26
  • 42
  • `attr.transform = CGAffineTransformMakeScale(0, 0);` works. The other doesn't actually shrink the size of the cell. – ricky3350 Jul 21 '14 at 01:15
0

In addition to duci9y's answer, (using attr.transform = CGAffineTransformMakeScale(0,0);), the following makes the tiles slide. I can't believe I didn't think of this before.

[self.collectionView performBatchUpdates:^{
    [self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
    [dataSource removeObjectAtIndex:indexPath.row];
} completion:nil];
ricky3350
  • 1,710
  • 3
  • 20
  • 35
  • That may cause animation errors. I suggest you change the `center` property of `attr` to go off the screen along with the `transform` to get the desired effect. – duci9y Jul 21 '14 at 21:15