数据集之间的UICollectionViewFlowLayout动画

时间:2014-01-17 19:56:12

标签: ios objective-c animation uicollectionview

我有一个UICollectionView,当按下一个单元格时,会有一组新的数据,并会为流程布局设置动画。

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSMutableArray *tempArray = [[NSMutableArray alloc] init];
    for(int i=0;i<200;i++)
    {
        [tempArray addObject:[NSNumber numberWithInt:i]];
    }

    items = [NSArray arrayWithArray:tempArray];

   CollapseLayout *currentLayout = (CollapseLayout *)_collectionView.collectionViewLayout;
currentLayout.collapse = YES;
[self.collectionView performBatchUpdates:^{
    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.collectionView.numberOfSections)]];
} completion:nil];
}

它使用自定义UICollectionViewFlowLayout在重新加载数据时执行动画。 我的CustomFlowLayout类在这里

#import "CollapseLayout.h"

@implementation CollapseLayout
- (void)prepareLayout {
    self.itemSize = CGSizeMake(200, 100);
    self.minimumInteritemSpacing = 30;
    self.scrollDirection = UICollectionViewScrollDirectionVertical;
}

- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSArray* allAttributesInRect = [super layoutAttributesForElementsInRect:rect];
    if(_collapse)
    {
         for(UICollectionViewLayoutAttributes *attribute in allAttributesInRect)
         {
             attribute.frame = CGRectMake(attribute.frame.origin.x - self.collectionView.frame.size.width, attribute.frame.origin.y, attribute.frame.size.width, attribute.frame.size.height);
         }
    }
    return allAttributesInRect;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewLayoutAttributes* allAttributesInRect = [super layoutAttributesForItemAtIndexPath:indexPath];
    if(_collapse)
    {
         allAttributesInRect.frame = CGRectMake(allAttributesInRect.frame.origin.x - self.collectionView.frame.size.width, allAttributesInRect.frame.origin.y, allAttributesInRect.frame.size.width, allAttributesInRect.frame.size.height);
    }
    return allAttributesInRect;
}

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}

- (UICollectionViewLayoutAttributes*)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath*)itemIndexPath
{
    UICollectionViewLayoutAttributes* layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:itemIndexPath];

    return layoutAttributes;
}

- (void)invalidateLayout
{

}

BOOL

_collapse 
在我的集合视图中调用

来触发动画。我希望旧的单元格从左到右移动到视图外部,新单元格从屏幕右侧生成动画。现在,细胞正在离开屏幕。

我的问题是layoutAttributesForItemAtIndexPath和layoutAttributesForElementsInRect中的代码没有正确动画。在这些方法中添加动画代码是执行动画的最佳位置,还是我完全关闭? 感谢

1 个答案:

答案 0 :(得分:1)

你不应该对

的结果做任何事情
[super layoutAttributesForItemAtIndexPath:indexPath];

,也不

[super layoutAttributesForElementsInRect:rect];

如果你希望你的细胞从它们离开屏幕的地方动画,那么你需要通过覆盖finalAttributesForDisappearingElementAtIndexPath:而不是它们的“常规位置”来修改它们的“最终”位置。

如果您希望他们从屏幕一侧返回,那么您需要通过initialLayoutAttributesForAppearingItemAtIndexPath:修改其位置