【问题标题】:CABasicAnimation rotate returns to original positionCABasicAnimation 旋转返回原始位置
【发布时间】:2011-12-02 18:26:30
【问题描述】:

我正在使用 CABasicAnimation 旋转 CALayer 并且工作正常。问题是,当我尝试旋转同一图层时,它会在旋转之前返回到原来的位置。我的预期输出是,对于下一次轮换,它应该从它结束的地方开始。这是我的代码:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
animation.fromValue         = 0;
animation.toValue           = [NSNumber numberWithFloat:3.0];
animation.duration          = 3.0;
animation.timingFunction    = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.removedOnCompletion = NO;
animation.fillMode          = kCAFillModeForwards;
animation.autoreverses      = NO;
[calayer addAnimation:animation forKey:@"rotate"];

我的代码有什么遗漏吗?谢谢

【问题讨论】:

    标签: ios calayer rotation cabasicanimation


    【解决方案1】:

    发生的情况是您在表示层中看到了动画。但是,这不会更新图层的实际位置。因此,一旦动画结束,您会看到图层原样,因为它没有改变。

    "Core Animation Rendering Architecture" 真的很值得一读。否则这会很混乱。

    要修复它,请为您的CABasicAnimation 设置一个委托,如下所示:

    [animation setDelegate:self];

    然后,创建一个方法来设置动画完成时所需的目标属性。现在,这是令人困惑的部分。您应该在 animationDidStart 而不是 animationDidStop 上执行此操作。否则,表示层动画将完成,当您在原始位置看到calayer 时会出现闪烁,然后它会跳转(没有动画)到目标位置。试试animationDidStop,你就会明白我的意思了。

    我希望这不会太混乱!

    - (void)animationDidStart:(CAAnimation *)theAnimation
    {
        [calayer setWhateverPropertiesExpected];
    }
    

    编辑:

    我后来发现 Apple 推荐了一种更好的方法来做到这一点。

    Oleg Begemann 在他的博文 Prevent Layers from Snapping Back to Original Values When Using Explicit CAAnimations

    中对正确的技术进行了很好的描述

    基本上你所做的是在开始动画之前,记下图层的当前值,即原始值:

    // Save the original value
    CGFloat originalY = layer.position.y;
    

    接下来,在层的模型上设置 toValue。因此,图层模型具有您将要执行的任何动画的最终值

    // Change the model value
    layer.position = CGPointMake(layer.position.x, 300.0);
    

    然后,您将动画设置为 fromValue 是您上面提到的原始值:

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.y"];
    
    // Now specify the fromValue for the animation because
    // the current model value is already the correct toValue
    animation.fromValue = @(originalY);
    animation.duration = 1.0;
    
    // Use the name of the animated property as key
    // to override the implicit animation
    [layer addAnimation:animation forKey:@"position"];
    

    请注意,为清楚起见,上面编辑中的代码是从 Ole Begemann 的博客中复制/粘贴的

    【讨论】:

    • 如何使用关键路径(例如 transform.rotation.y )来做到这一点?
    • 对我来说,为动画设置一个键并不能代替隐式动画,所以我不得不改用this answer
    【解决方案2】:

    如果您希望动画从结束处开始,则将fromValue 属性设置为CALayer 的当前旋转。

    获得该值很棘手,但这篇 SO 帖子向您展示了如何:https://stackoverflow.com/a/6706604/1072846

    【讨论】:

    • 我认为这比另一个建议使用 [animationDidStart:] 的答案更合适,这就是发布者想要的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    相关资源
    最近更新 更多