How do you set the duration for UICollectionView Animations?

后端 未结 9 2074
旧巷少年郎
旧巷少年郎 2020-12-12 17:07

I have a custom flow layout which is adjusting the attributes for cells when they are being inserted and deleted from the CollectionView with the following two functions, bu

9条回答
  •  悲&欢浪女
    2020-12-12 17:29

    To solve problem without hack that was proposed in the answer by gavrix you could subclass UICollectionViewLayoutAttributes with new property CABasicAnimation *transformAnimation, than create custom transformation with a suitable duration and assign it to attributes in initialLayoutAttributesForAppearingItemAtIndexPath, then in UICollectionViewCell apply the attributes as needed:

    @interface AnimationCollectionViewLayoutAttributes : UICollectionViewLayoutAttributes
    @property (nonatomic, strong)  CABasicAnimation *transformAnimation;
    @end
    
    @implementation AnimationCollectionViewLayoutAttributes
    - (id)copyWithZone:(NSZone *)zone
    {
        AnimationCollectionViewLayoutAttributes *attributes = [super copyWithZone:zone];
        attributes.transformAnimation = _transformAnimation;
        return attributes;
    }
    
    - (BOOL)isEqual:(id)other {
        if (other == self) {
            return YES;
        }
        if (!other || ![[other class] isEqual:[self class]]) {
            return NO;
        }
        if ([(( AnimationCollectionViewLayoutAttributes *) other) transformAnimation] != [self transformAnimation]) {
            return NO;
        }
    
        return YES;
    }
    @end
    

    In Layout class

    - (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath {
        AnimationCollectionViewLayoutAttributes* attributes = (AnimationCollectionViewLayoutAttributes* )[super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath];
    
        CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
        transformAnimation.duration = 1.0f;
        CGFloat height = [self collectionViewContentSize].height;
    
        transformAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0, 2*height, height)];
        transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0, attributes.bounds.origin.y, 0)];
        transformAnimation.removedOnCompletion = NO;
        transformAnimation.fillMode = kCAFillModeForwards;
        attributes.transformAnimation = transformAnimation;
        return attributes;
    }
    
    + (Class)layoutAttributesClass { 
        return [AnimationCollectionViewLayoutAttributes class]; 
    }
    

    then in UICollectionViewCell apply the attributes

    - (void) applyLayoutAttributes:(AnimationCollectionViewLayoutAttributes *)layoutAttributes
    {
        [[self layer] addAnimation:layoutAttributes.transformAnimation forKey:@"transform"];
    }
    

提交回复
热议问题