2011-05-07 77 views
8

我知道一个CALayer的shadowPath只能使用显式动画进行动画制作,但是我仍然无法让它工作。我怀疑我没有正确通过toValue - 据我所知这必须是id,但该属性需要CGPathRef。将其存储在UIBezierPath似乎不起作用。我使用下面的代码进行测试:动画CALayer的shadowPath属性

CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:@"shadowPath"]; 
theAnimation.duration = 3.0; 
theAnimation.toValue = [UIBezierPath bezierPathWithRect:CGRectMake(-10.0, -10.0, 50.0, 50.0)]; 
[self.view.layer addAnimation:theAnimation forKey:@"animateShadowPath"]; 

(我使用负值,以确保阴影延伸超过位于其顶部视图...层的masksToBounds属性设置为NO) 。

shadowPath的动画是如何实现的?

UPDATE

问题解决。不幸的是,主要的问题是一个粗心的错误...

我犯的错误是将动画添加到视图控制器的根层,而不是我专用于阴影的图层。另外,@ pe8ter是正确的,因为toValue需要是CGPathRef转换为id(很明显,当我之前尝试过,因为错误的层错误,我还没有动画)。该动画作品用下面的代码:

CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:@"shadowPath"]; 
theAnimation.duration = 3.0; 
theAnimation.toValue = (id)[UIBezierPath bezierPathWithRect:myRect].CGPath; 
[controller.shadowLayer addAnimation:theAnimation forKey:@"shadowPath"]; 

我明白,这是很难从我提供的示例代码被发现。但希望它仍然可以用于类似情况的人们。

然而,当我尝试并添加行

controller.shadowLayer.shadowPath = [UIBezierPath bezierPathWithRect:myRect].CGPath; 

动画停止工作,和阴影只是跳转到最终位置瞬间。 Docs说要使用与要更改的属性相同的键添加动画,以覆盖在设置属性值时创建的隐式动画,但shadowPath无法生成隐式动画...因此,如何获取新属性在之后留下动画?

+0

对不起,没有帮助。我能想到的唯一选择是使用'CALayer'的委托来显式设置_after_动画。请参阅[本文](http://stackoverflow.com/questions/2559812/cabasicanimation-not-changing-its-position-property-after-animation-completes)。 – pe8ter 2011-05-08 20:06:32

+0

@ pe8ter:太近了!我遵循这个伟大的建议,但在animationDidStop:截获动画并设置框架之前,原始shadowPath有一个非常轻微的闪光。太令人沮丧了。这可能是因为我必须遍历一小组视图控制器来为每个动画标识正确的图层,尽管我怀疑委托方法只是在已经将shadowPath设置为其原始价值。 – Stuart 2011-05-08 21:59:30

+0

很难说你的代码出了什么问题。我嘲笑了一个小测试程序并尝试了两种方法;他们按预期工作,没有任何视觉伪影。 – pe8ter 2011-05-09 01:32:36

回答

7

首先,您没有设置动画的fromValue。其次,你是对的:toValue接受CGPathRef,除了它需要被转换为id。做这样的事情:

theAnimation.toValue = (id)[UIBezierPath bezierPathWithRect:newRect].CGPath; 

你还需要,如果你想改变保持动画后明确设置层的shadowPath财产。

+0

感谢您的回复。我没有设置'fromValue',因为根据文档它是可选的(我从当前路径开始动画)。在压制编译器警告的同时强制转换为id,仍然没有解决我的问题。对于明确设置shadowPath属性以保留动画后的更改,我们没有看到任何动画,所以我认为这个问题必须存在于别处。 – Stuart 2011-05-08 15:31:35

+0

现在到达 - 不小心将动画发送到错误的图层。在动画之后保留shadowPath的新值时遇到了问题 - 我更新了我的问题。 – Stuart 2011-05-08 17:23:38

+1

时间吃一些卑微的馅饼。你第一个建议设置'fromValue'已经解决了我的问题。我必须承认它对我来说似乎有点奇怪,但由于某些原因,显式声明'fromValue'为当前路径允许动画在设置属性时正常进行。我希望文档对此更清楚。感谢您所有的帮助。 – Stuart 2011-05-09 18:38:52

1
let cornerRadious = 10.0 
     // 
     let shadowPathFrom = UIBezierPath(roundedRect: rect1, cornerRadius: cornerRadious) 
     let shadowPathTo = UIBezierPath(roundedRect: rect2, cornerRadius: cornerRadious) 
     // 
     layer.masksToBounds = false 
     layer.shadowColor = UIColor.yellowColor().CGColor 
     layer.shadowOpacity = 0.6 
     // 
     let shadowAnimation = CABasicAnimation(keyPath: "shadowPath") 
     shadowAnimation.fromValue = shadowPathFrom.CGPath 
     shadowAnimation.toValue = shadowPathTo.CGPath 
     shadowAnimation.duration = 0.4 
     shadowAnimation.autoreverses = true 
     shadowAnimation.removedOnCompletion = true 
     shadowAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) 
     layer.addAnimation(shadowAnimation, forKey: "shadowAnimation")