larryryu / LSSwipeToDeleteCollectionViewLayout

The UICollectionViewLayout subclass adds swipe to delete functionality to a collectionview
MIT License
41 stars 4 forks source link

Cells jump around after deletion if cells have different heights #8

Closed SkyTrix closed 9 years ago

SkyTrix commented 9 years ago

Deletion animation seems to work well when all cells have the same height. But when they all have different heights, everything starts to jump around after deletion.

larryryu commented 9 years ago

Could you provide sample code of how you are providing different sizes for the cells.

Thanks!

SkyTrix commented 9 years ago

I'm doing it like so:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CGFloat width = CGRectGetWidth(collectionView.bounds);

    STCard *card = (STCard *)[self.cards objectAtIndex:(NSUInteger)indexPath.row];
    Class cardCell = NSClassFromString(card.cardCellTypeString);

    CGFloat height = [cardCell heightForCard:card width:width];

    return CGSizeMake(width, height);
}
larryryu commented 9 years ago

So height is a function of the card type/class and width which should always return the same value as long as both type and width don't change for a given indexPath.row and constant datasource . I am not able to reproduce this yet.

here is what i have tried...

-(void)resetColors{
    colors = @[[UIColor redColor], [UIColor purpleColor], [UIColor orangeColor], [UIColor greenColor], [UIColor redColor], [UIColor blueColor], [UIColor orangeColor], [UIColor greenColor], [UIColor redColor], [UIColor blueColor], [UIColor orangeColor], [UIColor greenColor]].mutableCopy;

    CGSize size1 = CGSizeMake(200.0f, 200.0f);
    CGSize size2 = CGSizeMake(250.0f, 200.0f);
    CGSize size3 = CGSizeMake(200.0f, 250.0f);
    CGSize size4 = CGSizeMake(250.0f, 250.0f);

    sizes = @[[NSValue valueWithCGSize:size1], [NSValue valueWithCGSize:size2], [NSValue valueWithCGSize:size3], [NSValue valueWithCGSize:size4], [NSValue valueWithCGSize:size1], [NSValue valueWithCGSize:size2], [NSValue valueWithCGSize:size3], [NSValue valueWithCGSize:size4], [NSValue valueWithCGSize:size1], [NSValue valueWithCGSize:size2], [NSValue valueWithCGSize:size3], [NSValue valueWithCGSize:size4]].mutableCopy;
}

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
    return [[sizes objectAtIndex:indexPath.row] CGSizeValue];
}

-(void)swipeToDeleteLayout:(LSSwipeToDeleteCollectionViewLayout *)layout didDeleteCellAtIndexPath:(NSIndexPath *)indexPath{
    [colors removeObjectAtIndex:indexPath.row];
    [sizes removeObjectAtIndex:indexPath.row];
}

I think i need to see more of the code, maybe share through email if not comfortable showing it here.

larryryu commented 9 years ago

you may also try commenting out these lines in LSSwipeToDeleteCollectionViewLayout.m . They could potentially return the wrong attributes of an indexPath after deletion has occurred. I Plan to remove those in the next update.

- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
    return [self layoutAttributesForItemAtIndexPath:itemIndexPath];
}

- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
    return [self layoutAttributesForItemAtIndexPath:itemIndexPath];
}
SkyTrix commented 9 years ago

Thanks for the quick replies. I'll make a sample project when I get back near a laptop.

I had already run into an issue with the code above by the way. After deleting a few cells the app would crash because - layoutAttributesForItemAtIndexPath: calls super with an indexPath which is out of bounds.

SkyTrix commented 9 years ago

I just tried the sample project with the code you tried. I also see the issue there, though you might need to change the heights a bit to see it more clearly.

CGSize size1 = CGSizeMake(200.0f, 50);
CGSize size2 = CGSizeMake(250.0f, 200.0f);
CGSize size3 = CGSizeMake(200.0f, 20);
CGSize size4 = CGSizeMake(250.0f, 250.0f);

When deleting the purple cell, you'll see the orange one becoming the size of the purple cell before changing to its right size.

Also, try deleting the one before last cell after launching the sample project. It will always crash.

Removing the code below like you suggested fixes both issues. I have created a pull request for the change. Could you please bump the version number and push to CocoaPods?

- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
    return [self layoutAttributesForItemAtIndexPath:itemIndexPath];
}

- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
    return [self layoutAttributesForItemAtIndexPath:itemIndexPath];
}
larryryu commented 9 years ago

I merged the code and bumped the version number. Thanks for the contributions!!! :smile: :+1: