什么时候在iOS中发生隐式动画?

时间:2011-01-20 15:56:39

标签: ios core-animation

每个人和每本书都声称CALayer中存在隐式动画。但是,每次我想验证到目前为止,我最终都会严格按照设定值进行验证。完全没有动画。

这是项目中没有其他任何事情发生的例子。我所做的只是创建一个视图,然后获取它的CALayer实例并执行一些应该隐式动画的内容。

[theLayer setValue:[NSNumber numberWithFloat:M_PI * 1.1] forKeyPath:@"transform.rotation.z"];

另一个:

CGRect currentBounds = theLayer.bounds;
currentBounds.size.width += 120.f;
[self.animatedLayer setBounds:currentBounds];

视图包含一些东西,所以我可以看到变化。 我看到了视觉上的变化,但却是一个难以捉摸的瞬间。根本没有动画。

因此,在撰写关于核心动画和隐式动画的内容时,要么所有这些书都是错误的,并且考虑到旧的Mac OS X知识,或者我做错了什么。任何人都可以提供一个演示iPhone上隐式动画的工作示例吗?

6 个答案:

答案 0 :(得分:65)

UIKit禁用隐式动画。更具体地说,与UIView关联的CALayer永远不会隐式动画。您自己创建且与UIView无关的CALayers将购买正常的隐式动画机制。

如果您对这是如何工作感兴趣的话,隐式动画会在正常的-actionForKey:lookup之后发生。如果给定属性有CAAction,则使用它。否则,使用隐式动画。在与UIView关联的CALayer的情况下,UIView实现-actionForLayer:forKey:委托方法,当不在UIView动画块中时,它总是返回[NSNull null]以表示动作查找应该在此处停止。这可以防止隐式动画工作。在UIView动画块内部,它构造自己的动作来表示当前的UIView动画设置。同样,这可以防止隐式动画。

如果您需要为UIView不为您做的CALayer属性设置动画,您可以使用显式CAAnimation子类(例如CABasicAnimation)。

答案 1 :(得分:2)

旧帖子,但下面的链接指向核心动画编程指南中的一个部分,有助于更多地了解Kevin Ballard所说的内容。确实需要有一个明显的注释,提到为了动画UIView的底层图层属性,您需要确保将图层的委托设置为将采用“actionForLayer:ForKey:”方法并返回nil的实例。已经发现你也可以将委托设置为一个不采用这种方法的实例,它仍然允许隐式动画,但这是一个草率和令人困惑的做法。

Core Animation - Layer Actions - Defined Search Pattern for Action Keys

答案 2 :(得分:1)

请记住,UIView主图层的子图层通常不会将UIView作为其委托。因此,他们参与隐式动画,除非你明确地阻止它,即使你没有提供一个委托来响应actionForLayer返回一个nil动作:forKey:。

因此,在通用视图中获取隐式动画的一种简单方法就是添加一个覆盖主图层的子图层。

Matt Neuberg的书“编程iOS 5”(目前在Safari Books Online上测试版)非常清晰地解释了这个主题。

答案 3 :(得分:1)

Kevin Ballard的答案完全正确。我想在这里提供更多内容。

official document

的详细信息

有一节叫做:在iOS中修改图层的规则,你会发现

  

UIView类默认禁用图层动画,但在动画块内重新启用它们。

除了在UIView动画块中启用隐式外。还有另外两个解决方案:

  1. 使您需要的图层成为视图的子图层。请参阅[答案] [2]

    [2]:隐式动画淡入的Implicit property animations do not work with CAReplicatorLayer?不起作用。我试过这个,它按预期工作。

  2. 将图层的委托分配给图层本身。 iOS中图层的默认委托是其后备存储视图,该视图实现了actionForLayer:(id)图层forKey:(NSString *)键并返回[NSNull null]以禁用图层的隐式动画。

答案 4 :(得分:0)

您还可以将图层的委托设置为您自己的对象并处理-actionForLayer:forKey:。看起来好像你得到隐式动画,即使委托没有实现-actionForLayer:forKey:。

答案 5 :(得分:0)

实际上,您可以返回nil来获取CALay的默认动画。

  • (id)actionForLayer:(CALayer *)layer forKey:(NSString *)event { 返回零; }