Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
289 views
in Technique[技术] by (71.8m points)

ios - Animating CALayer's shadowPath property

I am aware that a CALayer's shadowPath is only animatable using explicit animations, however I still cannot get this to work. I suspect that I am not passing the toValue properly - as I understand this has to be an id, yet the property takes a CGPathRef. Storing this in a UIBezierPath does not seem to work. I am using the following code to test:

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

(I am using minus values so as to ensure the shadow extends beyond a view that lies on top of it... the layer's masksToBounds property is set to NO).

How is animation of the shadowPath achieved?

UPDATE

Problem nearly solved. Unfortunately, the main problem was a somewhat careless error...

The mistake I made was to add the animation to the root layer of the view controller, rather than the layer I had dedicated to the shadow. Also, @pe8ter was correct in that the toValue needs to be a CGPathRef cast to id (obviously when I had tried this before I still had no animation due to the wrong layer mistake). The animation works with the following code:

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

I appreciate this was difficult to spot from the sample code I provided. Hopefully it can still be of use to people in a similar situation though.

However, when I try and add the line

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

the animation stops working, and the shadow just jumps to the final position instantly. Docs say to add the animation with the same key as the property being changed so as to override the implicit animation created when setting the value of the property, however shadowPath can't generate implicit animations... so how do I get the new property to stay after the animation?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Firstly, you did not set the animation's fromValue.

Secondly, you're correct: toValue accepts a CGPathRef, except it needs to be cast to id. Do something like this:

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

You'll also need to set the shadowPath property of the layer explicitly if you want the change to remain after animation.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...