替代使用CABasicAnimation回调?

CAAnimation不提供分配除标准“animationDidStart:”/“animationDidStop:”方法之外的回调函数的机制。

我有一个自定义的UIControl,它使用了两个重叠的CALayers。 这种控制的目的类似于一个老式的声纳。 顶层的内容包含一个不断旋转的图像(称之为“魔杖”)。 该层下面是一个“spriteControl”层,当魔杖越过它们时呈现闪烁。

这些blips代表的对象被spriteControl预取并组织成不可见的CAShapeLayers。 我正在使用CABasicAnimation一次旋转魔杖10度,然后利用“animationDidStop:”方法调用spriteControl上的一个方法,该方法使用魔杖图层的当前旋转值(又称为标题),并将Alpha设置的动画设置为1.0到0.0用于模拟闪烁和淡出效果。 最后,这个过程无限期地重新开始。

尽管使用CAAnimation回调的这种方法确保了棒到达“ping”位置(即,10deg,20deg,270deg等)的时间总是与另一层中的blip的发光一致,但是存在停止,重新计算并每10度开始一次动画。

我可以产生一个NSTimer来激发一个方法来查询魔杖表示层的角度来获取标题值。 然而,这使得难以保持魔杖和blip突出显示同步,并且/或者导致一些完全跳过。 这个方法在这里讨论一下:我如何回调CABasicAnimation动画?

所以我的问题是,如果不使用OpenGL ES重新实现控制,是否有任何事情可以提高棒图层旋转的性能。 (我意识到这可以在OpenGL环境中轻松解决,但是,在这里使用它需要进行大量的重新设计,这是不值得的。)虽然性能问题很小,但我不能动摇那种感觉简单而明显的是,我可以做到这一点将允许魔杖无限期地动画,而不会暂停执行昂贵的旋转计算。

这是一些代码:

- (void)rotateWandByIncrement
{
    if (wandShouldStop)
        return;

    CGFloat newRotationDegree = (wandRotationDegree + WAND_INCREMENT_DEGREES);
    if (newRotationDegree >= 360)
        newRotationDegree = 0;


    CATransform3D rotationTransform = CATransform3DMakeRotation(DEGREES_TO_RADIANS(newRotationDegree), 0, 0, 1);

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
    animation.toValue = [NSValue valueWithCATransform3D:rotationTransform];
    animation.duration = WAND_INCREMENT_DURATION;
    animation.fillMode = kCAFillModeForwards;
    animation.removedOnCompletion = FALSE;
    animation.delegate = self;

    [wandLayer addAnimation:animation forKey:@"transform"];
}

- (void)animationDidStart:(CAAnimation *)theAnimation
{
    if (wandShouldStop)
        return;

    NSInteger prevWandRotationDegree = wandRotationDegree - WAND_INCREMENT_DEGREES;
    if (prevWandRotationDegree < 0)
        prevWandRotationDegree += 360;

    // Pulse the spriteControl
    [[self spriteControl] pulseRayAtHeading:prevWandRotationDegree];
}

- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag
{
    // update the rotation var
    wandRotationDegree += WAND_INCREMENT_DEGREES;
    if (wandRotationDegree >= 360)
        wandRotationDegree = 0;

    // This applies the rotation value to the model layer so that
    // subsequent animations start where the previous one left off
    CATransform3D rotationTransform = CATransform3DMakeRotation(DEGREES_TO_RADIANS(wandRotationDegree), 0, 0, 1);

    [CATransaction begin];
    [CATransaction setDisableActions:TRUE];
    [wandLayer setTransform:rotationTransform];
    [CATransaction commit];

    //[wandLayer removeAnimationForKey:@"transform"];
    [self rotateWandByIncrement];
}

假设雷达需要10秒完成一次完整的旋转。

为了让魔杖无限期地旋转,请将其Duration属性设置为10并将其RepeatCount属性设置为1e100f的CABasicAnimation附加到它。

可以使用他们自己的实例CAKeyframeAnimation进行动画CAKeyframeAnimation 。 我不会写详细信息,但是对于每个blip,您都指定一个不透明度值的数组(我认为不透明度是您如何淡出blipped)和一系列时间百分比(请参阅Apple的文档)。

链接地址: http://www.djcxy.com/p/74205.html

上一篇: Alternative to using CABasicAnimation callbacks?

下一篇: Is there a way to pause a CABasicAnimation?