UICollectionView动画(插入/删除项目)

时间:2013-05-22 11:41:32

标签: iphone ios objective-c uicollectionview uicollectionviewcell

我想在插入和/或删除UICollectionViewCell时自定义动画样式。

我需要这个的原因是默认情况下我看到插入一个单元格在动画中有一个平滑的淡入淡出,但删除一个单元格有一个向左移动+淡出动画的组合。如果不是一个问题,我会很高兴。

我删除一个单元格后,当我添加一个单元格时它仍会重复使用,当它重新使用时,它不会添加默认的淡入淡出效果,而是一个向左移动+淡入的组合。

我不确定为什么我在动画中出现这种不一致的原因。如果这是一个已知的错误/问题/愚蠢(在我这边:) :)请让我知道如何解决它。

否则,让我知道如何在删除单元格时设置自定义动画(或指向我的教程)。

由于

更新

通过继承UICollectionViewFlowLayout并添加这行代码修复了奇怪的动画行为

- (UICollectionViewLayoutAttributes *) initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath {

      return nil;
}

就是这样! :)

2 个答案:

答案 0 :(得分:29)

如果您使用自己的UICollectionViewLayout子类,则可以实现以下方法:

  • initialLayoutAttributesForAppearingItemAtIndexPath:用于插入

  • finalLayoutAttributesForDisappearingItemAtIndexPath:删除

根据文档,您返回的属性将用作动画的起点,终点是布局返回的常规属性(或者与删除相反)。布局属性包括位置,alpha,变换...... 当然,编写自己的布局类比使用Apple提供的流布局要多得多。

编辑:要在评论中回答您的问题,这里是一个大小相同的项目行的布局的超级基本实现。

单元格具有frame,默认情况下,alpha为1.0(由layoutAttributesForItemAtIndexPath:定义)。删除后,其属性将从删除前的当前状态动画到finalLayoutAttributesForDisappearingItemAtIndexPath:设置的属性,这些属性对应于framealpha 0.0。所以它不会移动但会消失。但是,右侧的单元格将向左移动(因为indexPath已更改,因此frame设置为layoutAttributesForItemAtIndexPath:

- (CGSize)collectionViewContentSize
{
    NSInteger numberOfItems = [self.collectionView numberOfItemsInSection:0];
    return CGSizeMake(numberOfItems * ITEM_WIDTH, ITEM_HEIGHT);
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger index = [indexPath indexAtPosition:0];
    UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    attributes.frame = CGRectMake(index * ITEM_WIDTH, 0, ITEM_WIDTH, ITEM_HEIGHT);
    return attributes;
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray *attributes = [NSMutableArray new];
    NSUInteger firstIndex = floorf(CGRectGetMinX(rect) / ITEM_WIDTH);
    NSUInteger lastIndex = ceilf(CGRectGetMaxX(rect) / ITEM_WIDTH);
    for (NSUInteger index = firstIndex; index <= lastIndex; index++) {
        NSIndexPath *indexPath = [[NSIndexPath alloc] initWithIndexes:(NSUInteger [2]){ 0, index } length:2];
        [attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
    }
    return attributes;
}

- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath];
    attributes.alpha = 0.0;
    return attributes;
}

答案 1 :(得分:6)

下载circle Layout。这是一个使用

的自定义布局示例
initialLayoutAttributesForAppearingItemAtIndexPath:  
finalLayoutAttributesForDisappearingItemAtIndexPath:  

这将是一个很好的工作材料。