我如何成功地同时动画多个图层



我成功地将单个图层动画化,以改变其在屏幕上沿任意路径的位置。我现在正试图多次复制这个动画,给人一种东西在拐角处弯曲的错觉。我将代码放入cattransaction中,并将其放入循环中,每次循环的起始位置递增,然后在循环结束后提交cattransaction。我看到的效果是一样的,如果代码不是在循环中(也就是说,只有一个图层被动画),那么在动画结束时,所有的图层都出现了(在我的委托在动画结束时在animationDidStop中删除它们之前)

我写的代码如下:
NSArray* path = [board caclulatePath:s];
    [CATransaction begin];
    [CATransaction setValue:[NSNumber numberWithFloat:([path count] * 0.25)] forKey:kCATransactionAnimationDuration];
    for (int i = 0; i < 20; i++)
    {
        CALayer* laserLayer = [CALayer layer];
        laserLayer.bounds = CGRectMake(s.frame.origin.x, s.frame.origin.y + (10*i), 20, 10);
        laserLayer.position = CGPointMake(s.frame.origin.x + (s.frame.size.width / 2), s.frame.origin.y + (s.frame.size.height / 2) + (10*i));
        laserLayer.contents = (id)[UIImage imageNamed:@"Laser.png"].CGImage;
        [self.layer addSublayer:laserLayer];
        CAKeyframeAnimation* anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        anim.values = path;
        anim.duration = ([path count] * 0.25);
        anim.removedOnCompletion = NO;
        anim.delegate = self;
        anim.rotationMode = kCAAnimationRotateAuto;
        [anim setValue:@"Fire" forKey:@"Action"];
        [anim setValue:laserLayer forKey:@"Layer"];
        [laserLayer addAnimation:anim forKey:nil];
    }
    [CATransaction commit];

where [board calculatepath:s]返回一个NSValues的nssarray *,代表CGPoints。

我怎样才能达到我之后的效果(这是laser.png的多个副本遵循相同的路径)?[Laser.png是一个20px x 20px的红色方块];

实际的问题是每一层都在同一时间遵循相同的路径…解决方案是在延迟(someSmallFractionOfTime * i)后触发每个图层/动画,其中i是递增的。

所以我提取了动画部分作为一个新的函数/方法/消息(不管它叫什么)

- (void) kickoffLaserAnimationWithPath: (NSArray *) path  {
CGPoint start = [(NSValue*)[path objectAtIndex:0] CGPointValue];
CALayer* laserLayer = [CALayer layer];
laserLayer.bounds = CGRectMake(start.x, start.y, 20, 10);
laserLayer.position = CGPointMake(start.x, start.y);
laserLayer.contents = (id)[UIImage imageNamed:@"Laser.png"].CGImage;
[self.layer addSublayer:laserLayer];
CAKeyframeAnimation* anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
anim.values = path;
anim.duration = ([path count] * laserSpeed);
anim.removedOnCompletion = NO;
anim.delegate = self;
anim.rotationMode = kCAAnimationRotateAuto;
[anim setValue:@"Fire" forKey:@"Action"];
[anim setValue:laserLayer forKey:@"Layer"];
[laserLayer addAnimation:anim forKey:nil];
isAnimating = YES;
}

并在循环中调用,如下所示:

NSArray* path = [board caclulatePath:s];
    [CATransaction begin];
    [CATransaction setValue:[NSNumber numberWithFloat:([path count] * laserSpeed)] forKey:kCATransactionAnimationDuration];
    float numBetweenPoints = (float)((float)s.frame.size.height / (float)10) * 2;
    float delay = (laserSpeed / numBetweenPoints);
    for (int i = 0; i < [path count]; i++)
    {
        [self performSelector:@selector(kickoffLaserAnimationWithPath:) withObject:path afterDelay:(delay*i)];
    }
    [CATransaction commit];

瞧…

看看CAAnimationGroup。我想它可能适合你的问题。

最新更新