UICollectionView performBatchUpdates: animates all sections

后端 未结 1 1294
不思量自难忘°
不思量自难忘° 2021-01-31 21:16

I\'m writing a custom UICollectionViewFlowLayout and I\'ve noticed that initialLayoutAttributesForAppearingItemAtIndexPath: and initialLayoutAttr

相关标签:
1条回答
  • 2021-01-31 22:08

    OK, I've got an answer; it's not a lot prettier than the previous one, but it keeps the layout from touching the datasource, so it's cleaner.

    Basically, we need to override prepareForCollectionViewUpdates: and finalizeCollectionViewUpdates to keep track of the sections that we're inserting. I have a mutable set that contains NSNumber instances of the sections that we're inserting.

    -(void)prepareForCollectionViewUpdates:(NSArray *)updateItems
    {
        [super prepareForCollectionViewUpdates:updateItems];
    
        [updateItems enumerateObjectsUsingBlock:^(UICollectionViewUpdateItem *updateItem, NSUInteger idx, BOOL *stop) {
            if (updateItem.updateAction == UICollectionUpdateActionInsert)
            {
                [insertedSectionSet addObject:@(updateItem.indexPathAfterUpdate.section)];
            }
        }];
    }
    
    -(void)finalizeCollectionViewUpdates
    {
        [super finalizeCollectionViewUpdates];
    
        [insertedSectionSet removeAllObjects];
    }
    

    Next, I check to see if the index path's section is included in that set when setting the initial layout attributes for items and decoration views.

    -(UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingDecorationElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)decorationIndexPath
    {
        UICollectionViewLayoutAttributes *layoutAttributes;
    
        if ([elementKind isEqualToString:AFCollectionViewFlowLayoutBackgroundDecoration])
        {
            if ([insertedSectionSet containsObject:@(decorationIndexPath.section)])
            {
                layoutAttributes = [self layoutAttributesForDecorationViewOfKind:elementKind atIndexPath:decorationIndexPath];
                layoutAttributes.alpha = 0.0f;
                layoutAttributes.transform3D = CATransform3DMakeTranslation(-CGRectGetWidth(layoutAttributes.frame), 0, 0);
            }
        }
    
        return layoutAttributes;
    }
    
    -(UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
    {
        UICollectionViewLayoutAttributes *layoutAttributes;
    
        if ([insertedSectionSet containsObject:@(itemIndexPath.section)])
        {
            layoutAttributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath];
            layoutAttributes.transform3D = CATransform3DMakeTranslation([self collectionViewContentSize].width, 0, 0);
        }
    
        return layoutAttributes;
    }
    

    I'm returning nil from these methods otherwise because nil is the default value.

    This has the added benefit of having nicer rotation animations, as well.

    0 讨论(0)
提交回复
热议问题