动画 CALayer 的 ShadowPath 属性
我知道 CALayer 的 ShadowPath 只能使用显式动画进行动画处理,但是我仍然无法使其工作。我怀疑我没有正确传递 toValue
- 据我所知,这必须是一个 id
,但该属性采用 CGPathRef。将其存储在 UIBezierPath 中似乎不起作用。我正在使用以下代码进行测试:(
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
属性设置为 否
)。
ShadowPath的动画是如何实现的?
更新
问题几乎解决了。不幸的是,主要问题是一个有点粗心的错误...
我犯的错误是将动画添加到视图控制器的根层,而不是我专用于阴影的层。另外,@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;
动画停止工作,并且阴影立即跳到最终位置。文档说使用与要更改的属性相同的键添加动画,以便覆盖设置属性值时创建的隐式动画,但是shadowPath无法生成隐式动画...那么我如何获取新属性停留在动画之后?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
首先,您没有设置动画的
fromValue
。其次,你是对的:
toValue
接受CGPathRef
,但它需要转换为id
。执行如下操作:如果您希望在动画之后保留更改,则还需要显式设置图层的
shadowPath
属性。Firstly, you did not set the animation's
fromValue
.Secondly, you're correct:
toValue
accepts aCGPathRef
, except it needs to be cast toid
. Do something like this:You'll also need to set the
shadowPath
property of the layer explicitly if you want the change to remain after animation.我在阴影动画中遇到了同样的问题,并找到了动画结束后持久阴影的解决方案。在开始动画之前,您需要设置阴影层的最终路径。恢复到初始阴影是因为 CoreAnimation 不会更新原始图层的属性,它会创建该图层的副本并在此副本上显示动画 (查看 Neko1kat 答案以获取更多详细信息)。动画结束后,系统会删除该动画图层并返回原始图层,该图层尚未更新路径,并且会出现旧的阴影。试试这个代码:
I've met same problem for shadow animation and find solution for persisting shadow after end of animation. You need to set final path to your shadow layer before you start animation. Reverting to initial shadow happens because CoreAnimation does not update properties of original layer, it creates copy of this layer and display animation on this copy (check Neko1kat answer for more details). After animation ended system removes this animated layer and return original layer, that has not updated path and your old shadow appears. Try this code:
虽然没有直接回答这个问题,但是如果你只需要一个可以投影的视图,你可以直接使用我的类。
通过 https://github.com /BB9z/iOS-Project-Template/blob/master/App/General/Effect/Shadow.swift
Although not directly answer this question, if you just needs a view can drop shadow, you can use my class directly.
via https://github.com/BB9z/iOS-Project-Template/blob/master/App/General/Effect/Shadow.swift