UICollectionView动画(插入/删除项目) [英] UICollectionView animations (insert/delete items)

查看:272
本文介绍了UICollectionView动画(插入/删除项目)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



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



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



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



谢谢



更新



通过子类化修复了奇怪的动画行为UICollectionViewFlowLayout并添加此行代码

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

返回零;
}

就是这样! :)

解决方案

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




  • initialLayoutAttributesForAppearingItemAtIndexPath: for insertionions


  • finalLayoutAttributesForDisappearingItemAtIndexPath:用于删除




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



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



一个单元格一个框架,默认情况下, alpha 为1.0(由 layoutAttributesForItemAtIndexPath定义:)。当它被删除时,其属性将从删除前的当前状态动画到由 finalLayoutAttributesForDisappearingItemAtIndexPath:设置的属性,它们对应于相同的框架 alpha 为0.0。所以它不会移动但会消失。但是,右边的单元格将被移动到左侧(因为它们的 indexPath 已更改,因此它们的框架 layoutAttributesForItemAtIndexPath设置:)。

   - (CGSize) collectionViewContentSize 
{
NSInteger numberOfItems = [self.collectionView numberOfItemsInSection:0];
返回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);
返回属性;
}

- (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] ;
[属性addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
}
返回属性;
}

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


I'd like to customize the animation styles when a UICollectionViewCell is inserted and/or deleted.

The reason why I need this is that by default I see that inserting a cell has a smooth fade in animation, however deleting a cell has a combination of move-to-the-left + fade out animation. I would be very happy with this if not for one problem.

After I delete a cell, it is still reused when I add new ones, and when it's reused it's added not with the default fade in effect, but instead it's a combination of move-to-the-left + fade in.

I'm not sure why I'm getting this inconsistency in animations. If this is a known bug/problem/stupidity(on my side :)) please let me know how to fix it.

Otherwise, let me know how to set custom animations when the cell is deleted (or point me towards a tutorial).

Thanks

UPDATE

Fixed the weird animation behavior by subclassing UICollectionViewFlowLayout and adding this line of code

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

      return nil;
}

That's it! :)

解决方案

If you use your own subclass of UICollectionViewLayout, you can implement the methods:

  • initialLayoutAttributesForAppearingItemAtIndexPath: for insertions

  • finalLayoutAttributesForDisappearingItemAtIndexPath: for deletions

According to the documentation, the attributes you return are used as starting points for the animation, and the end point are the normal attributes returned by your layout (or the opposite for deletion). Layout attributes include position, alpha, transform... Of course, it is more work to write your own layout class than to use the Apple provided flow layout.

Edit: To answer your question in the comments, here is a super basic implementation of a layout for rows of items which are all the same size.

A cell has a frame and, by default, an alpha of 1.0 (as defined by layoutAttributesForItemAtIndexPath:). When it is deleted, its properties will be animated from its current state before the deletion to the properties set by finalLayoutAttributesForDisappearingItemAtIndexPath:, which correspond to the same frame and an alpha of 0.0. So it won't move but it will fade out. However, the cells to the right are going to be moved to the left (because their indexPath has changed, and thus their frame as set by 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;
}

这篇关于UICollectionView动画(插入/删除项目)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆