替代使用CABasicAnimation回调?

CAAnimation不提供用于分配除标准“animationDidStart:”/“animationDidStop:”方法之外的回调函数的机制。 我有一个自定义UIControl,它使用2个重叠的CALayer。这种控制的目的类似于老式的声纳。顶层的内容包含一个不断旋转的图像(称此图层为“魔杖”)。在该图层下面是一个“spriteControl”图层,当魔杖经过它们时会呈现blips。 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秒钟。 要使魔杖无限旋转,请将
CABasicAnimation
连接到它,其
Duration
属性设置为10,其
RepeatCount
属性设置为1e100f。 每个blip都可以使用自己的实例
CAKeyframeAnimation
进行动画处理。我不会写详细信息,但是对于每个blip,你指定一个不透明度值数组(我假设不透明度是你淡出blip的方式)和一组时间百分比(参见Apple的文档)。     

要回复问题请先登录注册