ios gridview - 你如何设置UICollectionView动画的持续时间?




4 Answers

为了解决gavrix在答案中提出的问题,可以使用新属性CABasicAnimation *transformAnimation创建UICollectionViewLayoutAttributes的子类,然后创建具有适当持续时间的自定义转换,并将其分配给initialLayoutAttributesForAppearingItemAtIndexPath中的属性,然后在UICollectionViewCell中根据需要应用这些属性:

@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

在Layout类中

- (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;
}

然后在UICollectionViewCell中应用这些属性

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

我有一个自定义的流布局,正在调整单元格的属性,当他们被插入和从以下两个函数从CollectionView中删除,但我无法弄清楚如何调整默认的动画持续时间。

- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath {
UICollectionViewLayoutAttributes* attributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath];

// Assign the new layout attributes
attributes.transform3D = CATransform3DMakeScale(0.5, 0.5, 0.5);
attributes.alpha = 0;

return attributes;

}

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

UICollectionViewLayoutAttributes* attributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath];

// Assign the new layout attributes
attributes.transform3D = CATransform3DMakeScale(0.5, 0.5, 0.5);
attributes.alpha = 0;

return attributes;

}




基于@ rotava的答案,你可以通过批量更新集合视图来临时设置动画速度:

[self.collectionView performBatchUpdates:^{
    [self.collectionView.viewForBaselineLayout.layer setSpeed:0.2];
    [self.collectionView insertItemsAtIndexPaths: insertedIndexPaths];
} completion:^(BOOL finished) {
    [self.collectionView.viewForBaselineLayout.layer setSpeed:1];
}];



UICollectionView使用一些硬编码值在内部启动所有的动画。 但是,您始终可以重写该值直到提交动画。 一般来说,过程如下所示:

  • 开始动画
  • 获取所有的布局属性
  • 将属性应用于视图(UICollectionViewCell)
  • 提交动画

应用属性是在每个UICollectionViewCell下完成的,你可以用适当的方法重写animationDuration。 问题是,UICollectionViewCell有公共方法applyLayoutAttributes:但它的默认实现是空的! 基本上,UICollectionViewCell还有其他一些名为_setLayoutAttributes:私有方法_setLayoutAttributes:这个私有方法由UICollectionView调用,这个私有方法在最后调用applyLayoutAttributes:applyLayoutAttributes:之前,默认的布局属性,比如frame,position,transform被应用当前的animationDuration 。 这就是说,你必须在私有方法_setLayoutAttributes:重载animationDuration _setLayoutAttributes:

- (void) _setLayoutAttributes:(PSTCollectionViewLayoutAttributes *)layoutAttributes
{
    [UIView setAnimationDuration:3.0];
    [super _setLayoutAttributes:layoutAttributes];
}

显然,这不是安全的。 您可以使用这些运行时攻击之一来安全地重写此私有方法。




你可以改变UICollectionView layout.speed属性,这应该改变布局的动画持续时间...




Related

ios ios6 grid collectionview