【问题标题】:Sequence animation using CAAnimationGroup使用 CAAnimationGroup 的序列动画
【发布时间】:2013-07-19 19:38:40
【问题描述】:

我正在尝试制作一系列动画,我在CAAnimationGroup 中找到了实现该对象的正确类。在实践中,我在视图上添加了不同的子视图,我想用反弹效果为它们的条目设置动画,事实是我希望看到它们的动画在前一个完成后立即发生。我知道我可以设置委托,但我认为CAAnimationGroup 是正确的选择。
后来我发现组动画只能属于一个图层,但我需要它在屏幕上的不同图层上。当然在托管层不起作用。 有什么建议吗?

- (void) didMoveToSuperview {
    [super didMoveToSuperview];
    float startTime = 0;
    NSMutableArray * animArray = @[].mutableCopy;
    for (int i = 1; i<=_score; i++) {
        NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject: self.greenLeaf];
        UIImageView * greenLeafImageView = [NSKeyedUnarchiver unarchiveObjectWithData: archivedData];
        greenLeafImageView.image = [UIImage imageNamed:@"greenLeaf"];
        CGPoint leafCenter =  calculatePointCoordinateWithRadiusAndRotation(63, -(M_PI/11 * i) - M_PI_2);
        greenLeafImageView.center = CGPointApplyAffineTransform(leafCenter, CGAffineTransformMakeTranslation(self.bounds.size.width/2, self.bounds.size.height));
        [self addSubview:greenLeafImageView];

        //Animation creation
        CAKeyframeAnimation *bounceAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
        greenLeafImageView.layer.transform = CATransform3DIdentity;
        bounceAnimation.values = @[
                                  [NSNumber numberWithFloat:0.5],
                                  [NSNumber numberWithFloat:1.1],
                                  [NSNumber numberWithFloat:0.8],
                                  [NSNumber numberWithFloat:1.0]
                                  ];

        bounceAnimation.duration = 2;
        bounceAnimation.beginTime = startTime;
        startTime += bounceAnimation.duration;

        [animArray addObject:bounceAnimation];
        //[greenLeafImageView.layer addAnimation:bounceAnimation forKey:nil];


    }
    // Rotation animation
    [UIView animateWithDuration:1 animations:^{
        self.arrow.transform = CGAffineTransformMakeRotation(M_PI/11 * _score);
    }];
    CAAnimationGroup * group = [CAAnimationGroup animation];
    group.animations = animArray;
    group.duration = [[ animArray valueForKeyPath:@"@sum.duration"] floatValue];
    [self.layer addAnimation:group forKey:nil];
}

【问题讨论】:

    标签: ios objective-c cocoa-touch cocoa core-animation


    【解决方案1】:

    CAAnimationGroup 是为了让多个CAAnimation 子类堆叠在一起形成一个动画,例如,一个动画可以执行缩放,另一个可以移动它,而第三个可以旋转它,这不是意味着用于管理多个图层,但具有多个叠加动画。

    也就是说,我认为解决您的问题的最简单方法是为每个 CAAnimation 分配一个 beginTime 等于所有之前的持续时间的总和,以说明:

    for i in 0 ..< 20
    {
        let view : UIView = // Obtain/create the view...;
        let bounce = CAKeyframeAnimation(keyPath: "transform.scale")
    
        bounce.duration  = 0.5;
        bounce.beginTime = CACurrentMediaTime() + bounce.duration * CFTimeInterval(i);
    
        // ...
    
        view.layer.addAnimation(bounce, forKey:"anim.bounce")
    }
    

    请注意,每个人都会得到duration * i,而CACurrentMediaTime() 是使用beginTime 属性时的必需品(它基本上是“现在”的高精度时间戳,用于动画中)。整行可以解释为now + duration * i

    必须注意,如果将CAAnimations 添加到CAAnimationGroup,则其beginTime 将相对于组的开始时间,因此动画中5.0 的值将是@987654334 @整个小组开始后的几秒钟。在这种情况下,您不使用 CACurrentMediaTime()

    【讨论】:

      【解决方案2】:

      如果您查看the documentation,您会注意到CAAnimationGroup 继承自CAAnimation,并且CAAnimation 只能分配给一个CALayer。它的目的是让创建和管理您希望同时应用于CALayer 的多个动画变得容易,而不是管理多个CALayer 对象的动画。

      为了处理不同CALayerUIView对象之间不同动画的排序,我使用的一种技术是为每个对象/动画创建一个NSOperation,然后将它们放入NSOperationQueue来管理排序.这有点复杂,因为你必须使用动画完成回调来告诉NSOperation它已经完成了,但是如果你编写一个好的动画管理子类NSOperation,它会相当方便并允许你创建复杂的序列路径。实现排序目标的低成本方式是在您的CAAnimation 对象(来自它采用CAMediaTiming 协议)上简单地设置beginTime 属性,以获得您想要的时间。

      话虽如此,我将向您指出一些我编写并开源的代码,以解决您描述的完全相同的用例。您可能会发现它on github here(包括相同的代码)。我将添加以下注释:

      • 我的动画管理代码允许您通过识别图像更改、比例更改、位置更改等的顺序和时间来在 plist 中定义动画。实际上,在 plist 文件中调整动画比在 plist 文件中调整动画更方便、更简洁在代码中(这就是我写这个的原因)。
      • 如果不希望用户与您创建的子视图交互,那么创建作为子层添加到托管视图层的层对象实际上要好得多(开销更少)。

      【讨论】:

      • 我会研究一下这似乎是一个非常有趣的方法
      猜你喜欢
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 2014-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多