在Layer-Backed视图上使用核心动画 [英] Use core animation on an Layer-Backed view

查看:67
本文介绍了在Layer-Backed视图上使用核心动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

核心动画编程指南,有一段关于如何动画图层支持视图,它说:

In Core Animation Programming guide, there is one paragraph about How to Animate Layer-Backed Views, it says:


如果要使用Core Animation类来启动动画,则必须从基于视图的动画块中发出所有Core Animation调用。 UIView类默认禁用图层动画,但在动画块内重新启用它们。因此,您在动画块之外所做的任何更改都不会设置动画。

If you want to use Core Animation classes to initiate animations, you must issue all of your Core Animation calls from inside a view-based animation block. The UIView class disables layer animations by default but reenables them inside animation blocks. So any changes you make outside of an animation block are not animated.

还有一个示例:

[UIView animateWithDuration:1.0 animations:^{
   // Change the opacity implicitly.
   myView.layer.opacity = 0.0;

   // Change the position explicitly.
   CABasicAnimation* theAnim = [CABasicAnimation animationWithKeyPath:@"position"];
   theAnim.fromValue = [NSValue valueWithCGPoint:myView.layer.position];
   theAnim.toValue = [NSValue valueWithCGPoint:myNewPosition];
   theAnim.duration = 3.0;
   [myView.layer addAnimation:theAnim forKey:@"AnimateFrame"];
}];

在我看来,它告诉我如果不从视图内发出核心动画调用 - 基于动画块,没有动画。

In my opinion, it tells that if I don't issue Core Animation calls from inside a view-based animation block, there will no animation.

但是,如果我直接添加核心动画调用而没有基于视图的动画块,它的工作方式是相同的。

But it seems that if I add the core animation calls directly without view-based animation block, it works the same.

我错过了什么吗?

推荐答案

tl;博士: 文档仅涉及隐式动画。明确的动画在动画块之外工作正常。

tl;dr: The documentation only refers to implicit animations. Explicit animations work fine outside of animation blocks.

来自文档的引用的简化版本就像(我解释它):

The simplified version of that quote from the docs is something like (me paraphrasing it):


UIView已禁用隐式动画,但动画块内除外。如果你想做隐式图层动画,你必须在动画块内完成它们。

UIView have disabled implicit animations except for within animation blocks. If you want to do implicit layer animations you must do them inside an animation block.



什么是隐式动画以及它们如何工作?



隐式动画是独立图层的可动画属性发生变化时发生的动画。例如,如果您创建一个图层并更改它的位置,它将设置为新位置的动画。默认情况下,许多层属性都具有此行为。

What is implicit animations and how do they work?

Implicit animations is what happens when an animatable property of a standalone layer changes. For example, if you create a layer and change it's position it's going to animate to the new position. Many, many layer properties have this behaviour by default.

它发生如下:


  1. 系统启动一项交易(没有我们做任何事情)

  2. 属性的值已更改

  3. 图层查找该属性的操作

  4. 在某个时刻提交交易(没有我们做任何事情)

  5. 找到的行动已经应用

  1. a transaction is started by the system (without us doing anything)
  2. the value of a property is changed
  3. the layer looks for the action for that property
  4. at some point the transaction is committed (without us doing anything)
  5. the action that was found is applied

请注意,上面没有提到动画,而是有动作这个词。此上下文中的操作是指实现 CAAction 协议的对象。它很可能是一些CAAnimation子类(如CABasicAnimation,CAKeyframeAnimation或CATransition),但它可以与符合该协议的任何内容一起使用。

Notice that there is no mention of animation above, instead there is the word "action". An action in this context refers to an object which implements the CAAction protocol. It's most likely going to be some CAAnimation subclass (like CABasicAnimation, CAKeyframeAnimation or CATransition) but is built to work with anything that conforms to that protocol.

通过调用找到该属性的动作图层上的 actionForKey:。此默认实现按以下顺序查找操作:

Finding the action for that property happens by calling actionForKey: on the layer. The default implementation of this looks for an action in this order:

此搜索按此顺序进行(ref: actionForKey:文档

This search happens in this order (ref: actionForKey: documentation)



  1. 如果图层有一个委托并且该委托实现在访问图层的过滤器方法时,图层会调用该方法。代理人必须执行以下操作之一:


    • 返回给定密钥的操作对象。

    • 返回 nil 如果它不处理该动作。

    • 如果它返回 NSNull 对象不处理该操作,搜索应该终止。

  1. If the layer has a delegate and that delegate implements the Accessing the Layer’s Filters method, the layer calls that method. The delegate must do one of the following:
    • Return the action object for the given key.
    • Return nil if it does not handle the action.
    • Return the NSNull object if it does not handle the action and the search should be terminated.




UIView在做什么?



对于支持视图的图层,视图可以启用或禁用实施代表我thod actionForLayer:forKey 。对于正常情况(在动画块之外),视图通过返回 [NSNull null] 来禁用隐式动画,这意味着:

What is UIView doing?

In the case of layers that are backing views, the view can enable or disable the actions by implementing the delegate method actionForLayer:forKey. For normal cases (outside an animation block) the view disables the implicit animations by returning [NSNull null] which means:

它不处理动作,搜索应该终止。

it does not handle the action and the search should be terminated.

但是,在动画中阻止,视图返回一个真实的动作。通过在动画块内部和外部手动调用 actionForLayer:forKey:,可以轻松验证这一点。它也可能返回 nil 这会导致图层继续寻找一个动作,如果它之前找不到任何内容,最终会以隐式动作结束(如果有的话)那个。

However, inside the animation block, the view returns a real action. This can easily be verified by manually invoking actionForLayer:forKey: inside and outside the animation block. It could also have returned nil which would cause the layer to keep looking for an action, eventually ending up with the implicit actions (if any) if it wouldn't find anything before that.

当找到一个动作并且提交了事务时,使用常规的 addAnimation:forKey:机制。这可以通过创建自定义图层子类并在 -actionForKey: -addAnimation:forKey:中记录来轻松验证然后是一个自定义视图子类,您可以在其中覆盖 + layerClass 并返回自定义图层类。您将看到独立层实例记录两种方法以进行常规属性更改,但支持层不会添加动画,除非在动画块中。

When an action is found and the transaction is committed the action is added to the layer using the regular addAnimation:forKey: mechanism. This can easily be verified by creating a custom layer subclass and logging inside -actionForKey: and -addAnimation:forKey: and then a custom view subclass where you override +layerClass and return the custom layer class. You will see that the stand alone layer instance logs both methods for a regular property change but the backing layer does not add the animation, except when within a animation block.

现在,为什么我要对隐式动画的工作方式给出这么长的解释?好吧,这是为了表明他们使用与您自己使用的相同方法和明确的动画。知道它们是如何工作的,我们可以理解当文档说:UIView类默认禁用图层动画但在动画块中重新启用它们时它意味着什么。

Now, why did I give this very long explanation of how implicit animations work? Well, it's to show that they use the same methods that you use yourself with explicit animations. Knowing how they work, we can understand what it means when the documentation say: "The UIView class disables layer animations by default but reenables them inside animation blocks".

原因为什么UIView没有禁用显式动画,是你自己做的所有工作:更改属性值,然后调用 addAnimation:forKey:

The reason why explicit animations aren't disabled by what UIView does, is that you are doing all the work yourself: changing the property value, then calling addAnimation:forKey:.

动画块之外:

myView.backgroundColor       = [UIColor redColor];           // will not animate :(
myLayer.backGroundColor      = [[UIColor redColor] CGColor]; // animates :)

myView.layer.backGroundColor = [[UIColor redColor] CGColor]; // will not animate :(
[myView.layer addAnimation:myAnimation forKey:@"myKey"];     // animates :)

动画块内:

myView.backgroundColor       = [UIColor redColor];           // animates :)
myLayer.backGroundColor      = [[UIColor redColor] CGColor]; // animates :)

myView.layer.backGroundColor = [[UIColor redColor] CGColor]; // animates :)
[myView.layer addAnimation:myAnimation forKey:@"myKey"];     // animates :)

您可以在上面看到,独立图层上的显式动画和隐式动画会在外部生成动画并且在动画块内部,但是图层支持视图的隐式动画仅在动画块内部进行动画处理。

You can see above that explicit animations and implicit animations on standalone layers animate both outside and inside of animation blocks but implicit animations of layer-backed views does only animate inside the animation block.

这篇关于在Layer-Backed视图上使用核心动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆