【问题标题】:CABasicAnimation on strokeEndCABasicAnimation on strokeEnd
【发布时间】:2014-03-29 21:49:02
【问题描述】:

我有一个正方形的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 来实现相同的目标。

我能做的最好的是将CATransaction 块内的strokeEnd 设置为1 或0,并相应地设置fromValue。换句话说,我似乎无法在动画strokeEnd 时同时省略toValueendValue - 我至少需要其中一个(即fromValuetoValue)。

所以我的问题是,我怎样才能在完全不需要使用toValuefromValue 的情况下为strokeEnd 制作动画?

谢谢。

【问题讨论】:

  • 属性需要改变,就这样。
  • @DavidRönnqvist 然而,这似乎不是答案的一个小提示。
  • 为什么不想设置fromValuetoValue?这让我觉得这是最直观的方法,可以精确地指定你想要为 strokeEnd 设置动画的对象。

标签: ios animation core-animation cabasicanimation


【解决方案1】:

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

  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];
    

    注意,我不必指定@(1.0)toValue,因为它会自动默认为myLayer.strokeEnd 的当前值(在本例中恰好是1.0)。

Core Animation 的这两个不同方面相互作用的地方是,当您使用 CABasicAnimation 编写动画时,您不仅想指定动画,还想直接更改图层的属性,对在动画开始之前。

例如,如果我添加了一个CAShapeLayer 作为sublayer,但想要为它的前半部分绘制动画(即将strokeEnd0.0 动画到0.5),理论上你可能想要 (a) 指定 myLayer.shapeEnd 为最终值(例如 0.5); (b) 创建一个fromValue@(0.0)CABasicAnimation(但您可以省略toValue,因为我们已经将图层的shapeEnd 设置为适当的值)。但是,回到我回答开头的第 1 点,当我们直接设置图层属性时,例如myLayer.shapeEnd,您可能希望将setDisableActions 改为YES,因此没有尝试任何隐式动画(给定我们即将使用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 通常是不必要的,但从技术上讲,如果您正在设置图层的属性并且想要确保没有启动隐式动画,您可能希望使用setDisableActions,如图所示以上。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-28
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多