在strokeEnd上的CABasicAnimation

时间:2014-03-29 21:49:02

标签: ios animation core-animation cabasicanimation

我有一个正方形的CAShapeLayer,我将width设置为2.0f。

我想为其strokeEnd设置动画,为此我使用CABasicAnimation,如此:

CABasicAnimation *stroke = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
stroke.fromValue = @(0);
stroke.toValue = @(1); 
stroke.repeatCount = 1;
stroke.duration = 10.0f;
stroke.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[myLayer addAnimation:stroke forKey:nil];

它有效。从Matt Neuberg的书中我知道我们可以完全省略toValuefromValue

[CATransaction begin];
[CATransaction setDisableActions:YES];
..
..
[CATransaction commit];

然而,他的例子基于transform。我试图用strokeEnd来实现相同的目标。

我能做的最好的事情是将strokeEnd块中的CATransaction设置为1或0并相应地设置fromValue。其他的话我似乎无法在动画toValue上省略endValuestrokeEnd - 我至少需要其中一个(即fromValue或{{1 }})。

所以我的问题是,我怎样才能动画toValue而无需使用strokeEndtoValue

感谢。

1 个答案:

答案 0 :(得分:12)

这里有两个非常不同的问题:

  1. 如果您更改了某个图层的可动画属性(即不使用CABasicAnimation,而是直接在代码中更改图层的属性),Core Animation可能会将隐式动画应用于图层(相对较快)动画,但动画但是)。例如,如果更改myLayer.opacity,Core Animation可能会自动应用隐式动画来淡化此效果。同样,如果您直接更改myLayer.strokeEnd,它可能会为笔画结束的变化设置动画(您会看到它快速绘制线条,而不是立即显示)。

    通过使用[CATransaction setDisableActions:YES],您可以指示Core Animation不执行直接更改图层属性时可能应用的隐式动画。使用[CATransaction setDisableActions:NO],您将重新启用隐式动画。

  2. 创建CABasicAnimation时,有fromValuetoValuebyValue属性(根据文档,“所有都是可选的,并且不超过两个应该是非nil。“)。您经常会看到指定fromValuetoValue的动画。但是你想要,你可以指定一个,而Core Animation将决定其他人应该是什么。

    例如,我们假设您刚刚创建了CAShapeLayer(默认情况下,strokeEnd1.0)。然后,如果我想将strokeEnd的动画设置为0到100%,您可以使用:

    CABasicAnimation *stroke = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    stroke.fromValue = @(0.0);
    stroke.duration = 1.0f;
    [myLayer addAnimation:stroke forKey:nil];
    

    注意,我不必指定toValue的{​​{1}},因为它会自动默认为@(1.0)的当前值(在此示例中恰好为1.0)。

  3. 核心动画的这两个截然不同的方面是你使用myLayer.strokeEnd编写动画的时候,你不仅想要指定动画,而且还想改变图层的属性,直接,在动画开始之前。

    例如,如果我添加CABasicAnimation作为CAShapeLayer,但想要为其前半部分的绘图设置动画(即将sublayerstrokeEnd设置为动画0.0),您理论上可能希望(a)将0.5指定为最终值(例如myLayer.shapeEnd); (b)使用0.5 CABasicAnimation创建fromValue(但您可以省略@(0.0),因为我们已经将图层的toValue设置为适当的shapeEnd值)。但是,在我的答案开始时回到第1点,当我们直接设置图层属性时,例如myLayer.shapeEnd,您可能希望setDisableActionsYES,所以没有尝试在任何隐式动画中(假设我们将使用CABasicAnimation指定实际所需的动画)。

    // set the layer's strokeEnd directly (with no implicit animation)
    
    [CATransaction setDisableActions:YES];
    myLayer.strokeEnd = 0.5;
    [CATransaction setDisableActions:NO];
    
    // now animate the layer's stroke end from 0.0 to the final value,
    // which, because we didn't specify `toValue`, will default to the
    // current value of `myLayer.strokeEnd` (which we happened to set
    // right above)
    
    CABasicAnimation *stroke = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    stroke.fromValue = @0.0;
    stroke.duration = 1.0f;
    [myLayer addAnimation:stroke forKey:nil];
    

    在实践中,我发现setDisableActions通常是不必要的,但从技术上讲,如果您正在设置图层的属性并且您想确保没有启动隐式动画,您可能希望使用{{1} },如上所示。

    但是,正如您可能从此讨论中推断出的那样,我们不需要设置setDisableActions的事实不是使用toValue或其方法CATransaction的直接结果。此示例中不需要setDisableActions,因为我们在开始动画之前设置了图层toValue。我们恰好使用strokeEnd来确保在直接更改图层属性时没有启动隐式动画。