使用CAAnimationGroup的序列动画 [英] Sequence animation using CAAnimationGroup

查看:480
本文介绍了使用CAAnimationGroup的序列动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图制作一系列动画,我在 CAAnimationGroup 中找到了正确的类来实现该对象。在实践中,我添加了一个视图不同的子视图,我想用一个反弹效果动画他们的输入,事实是,我想看到他们的动画发生在前一个完成后。我知道我可以设置委托,但我认为 CAAnimationGroup 是正确的选择。

后来我发现组动画只能属于一个图层,但我需要它在屏幕上的不同图层上。当然在主机层不工作。
有些建议?

I'm trying to make a sequence of animations, I've found in CAAnimationGroup the right class to achieve that object. In practice I'm adding on a view different subviews and I'd like to animate their entry with a bounce effect, the fact is that I want to see their animations happening right after the previous has finished. I know that I can set the delegate, but I thought that the CAAnimationGroup was the right choice.
Later I discovered that the group animation can belong only to one layer, but I need it on different layers on screen. Of course on the hosting layer doesn't work. Some suggestions?

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


推荐答案

CAAnimationGroup 用于将多个 CAAnimation 子类堆叠在一起形成动画,例如,一个动画可以执行缩放,另一个动画可以执行缩放周围,​​而第三个可以旋转它,它不是用于管理多层,但有多个重叠的动画。

CAAnimationGroup is meant for having multiple CAAnimation subclasses being stacked together to form an animation, for instance, one animation can perform an scale, the other moves it around, while a third one can rotate it, it's not meant for managing multiple layers, but for having multiple overlaying animations.

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

That said, I think the easiest way to solve your issue, is to assign each CAAnimation a beginTime equivalent to the sum of the durations of all the previous ones, to illustrate:

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 当使用 beginTime 属性(它基本上是now的高精度时间戳,用于动画)时,CACurrentMediaTime()整行可以解释为 now + duration * i

Notice that everyone gets duration * i, and the CACurrentMediaTime() is a necessity when using the beginTime property (it's basically a high-precision timestamp for "now", used in animations). The whole line could be interpreted as now + duration * i.

必须注意,如果 CAAnimation s添加到 CAAnimationGroup ,则其 beginTime 到组的开始时间,因此动画上的 5.0 的值将是整个组开始后的 5.0 秒。在这种情况下,您不使用CACurrentMediaTime()

Must be noted, that if a CAAnimations is added to a CAAnimationGroup, then its beginTime becomes relative to the group's begin time, so a value of 5.0 on an animation, would be 5.0 seconds after the whole group starts. In this case, you don't use the CACurrentMediaTime()

这篇关于使用CAAnimationGroup的序列动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆