【问题标题】:How do I successfully animate multiple CALayers simultaneously?如何同时成功地为多个 CALayers 设置动画?
【发布时间】:2011-07-29 08:17:27
【问题描述】:

我成功地为单个图层设置动画,以沿屏幕上的任意路径更改其位置。我现在尝试多次复制这个动画,以产生某种东西在拐角处弯曲的错觉。我将代码放在 CATransaction 中,并将其放入循环中,为循环的每次迭代递增起始位置,然后在循环后提交 CATransaction。如果代码不在循环中(也就是说,只有一个图层被动画),那么我看到的效果是相同的,然后在动画结束时所有图层都会出现(在我的代表在动画结束时删除它们之前 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];

其中 [board caclulatePath:s] 返回代表 CGPoints 的 NSValues 的 NSArray*。

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

【问题讨论】:

    标签: iphone core-animation caanimation cakeyframeanimation catransaction


    【解决方案1】:

    实际的问题是每个层都在同一时间遵循相同的路径...解决方案是在 i 递增的 (someSmallFractionOfTime * 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];
    

    瞧……

    【讨论】:

      【解决方案2】:

      看看CAAnimationGroup。我认为它可能适合您的问题。

      【讨论】:

      • 会 +1 这个因为这是值得一看的东西,虽然它对我的问题没有帮助......
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 2019-06-15
      相关资源
      最近更新 更多