动画 CALayer 的蒙版大小变化
我有一个 UIView 子类,它在其 CALayer 上使用 CAShapeLayer 掩码。面具采用独特的形状,具有三个圆角,其余角有一个切出的矩形。
当我使用标准动画块调整 UIView
的大小时,UIView
本身及其 CALayer
的大小调整得很好。然而,蒙版是立即应用的,这会导致一些绘图问题。
我尝试使用 CABasicAnimation 为蒙版的大小调整设置动画,但没有成功地获得调整大小的动画。
我可以以某种方式在蒙版上实现动画调整大小效果吗?我是否需要去掉蒙版,或者我是否必须更改当前绘制蒙版的方式(使用 - (void)drawInContext:(CGContextRef)ctx
)。
干杯, 亚历克斯
I have a UIView
subclass which uses a CAShapeLayer
mask on its CALayer
. The mask uses a distinct shape, with three rounded corners and a cut out rectangle in the remaining corner.
When I resize my UIView
using a standard animation block, the UIView
itself and its CALayer
resize just fine. The mask, however, is applied instantly, which leads to some drawing issues.
I've tried animating the mask's resizing using a CABasicAnimation
but didn't have any luck getting the resizing animated.
Can I somehow achieve an animated resizing effect on the mask? Do I need to get rid of the mask, or will I have to change something about the way I currently draw the mask (using - (void)drawInContext:(CGContextRef)ctx
).
Cheers,
Alex
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
我找到了这个问题的解决方案。其他答案部分正确并且有帮助。
以下几点对于理解解决方案非常重要:
为了解决这个问题,我们必须自己利用核心动画,而不能依赖 UIView 动画块来为我们完成工作。
只需创建一个具有与
[UIView animateWithDuration:...]
相同持续时间的CATransaction
即可。这将创建一个单独的动画,但如果您的持续时间和缓动函数相同,则它应该与动画块中的其他动画完全相同。I found the solution to this problem. Other answers are partially correct and are helpful.
The following points are important to understanding the solution:
In order to solve, we are going to have to tap into Core Animation ourselves, and can't rely on the UIView animation block to do the work for us.
Simply create a
CATransaction
with the same duration that you are using with[UIView animateWithDuration:...]
. This will create a separate animation, but if your durations and easing function is the same, it should animate exactly with the other animations in your animation block.我使用 CAShapeLayer 通过将 self.layer.mask 设置为形状层来屏蔽 UIView。
为了在视图大小发生变化时对遮罩进行动画处理,我覆盖了
-setBounds:
,以便在动画期间更改边界时对遮罩层路径进行动画处理。以下是我的实现方式:(
例如,
self.maskLayer
设置为 `self.layer.mask)我的
-createMaskPath
计算我用来屏蔽视图的 CGPathRef 。我还更新了-layoutSubviews
中的遮罩路径。I use a
CAShapeLayer
to mask aUIView
by settingself.layer.mask
to that shape layer.To animate the mask whenever the size of the view changes I overwrote the
-setBounds:
to animate the mask layer path if the bounds are changed during an animation.Here's how I implemented it:
(For the example
self.maskLayer
is set to `self.layer.mask)My
-createMaskPath
calculates the CGPathRef that I use to mask the view. I also update the mask path in-layoutSubviews
.CALayer 的 mask 属性不可设置动画,这解释了您在这方面缺乏运气。
蒙版的绘制是否取决于蒙版的框架/边界? (您可以提供一些代码吗?)掩码是否设置了needsDisplayOnBoundsChange属性?
干杯,
科林
The mask property of CALayer is not animatable which explains your lack of luck in that direction.
Does the drawing of your mask depend on the frame/bounds of the mask? (Can you provide some code?) Does the mask have needsDisplayOnBoundsChange property set?
Cheers,
Corin
要对 UIView 的遮罩层的边界变化进行动画处理:子类 UIView,并使用 CATransaction 对遮罩进行动画处理 - 类似于 Kekodas 答案,但更通用:
To animate the bounds change of the mask layer of a UIView: subclass UIView, and animate the mask with a CATransaction - similar to Kekodas answer but more general:
mask 参数不会产生动画,但您可以对设置为 mask 的图层进行动画处理...
如果对 CAShapeLayer 的 Path 属性进行动画处理,则应该对 mask 进行动画处理。我可以从我自己的项目中验证这是否有效。但不确定是否使用非矢量掩码。您是否尝试过对蒙版的内容属性进行动画处理?
谢谢,
乔恩
The mask parameter doesn't animate, but you can animate the layer which is set as the mask...
If you animate the CAShapeLayer's Path property, that should animate the mask. I can verify that this works from my own projects. Not sure about using a non-vector mask though. Have you tried animating the contents property of the mask?
Thanks,
Jon
我找不到任何编程解决方案,所以我只是绘制一个具有正确形状和 alpha 值的 png 图像并使用它。这样我就不用戴口罩了
I couldn't find any programmatical solution so I just draw an png image with correct shape and alpha values and used that instead. That way I don't need to use a mask...
可以对蒙版变化进行动画处理。
我更喜欢使用 CAShapeLayer 作为遮罩层。借助属性路径来动画遮罩更改非常方便。
在对任何更改进行动画处理之前,将源内容转储到实例 CGImageRef 中,并为动画创建一个新层。在动画期间隐藏原始图层并在动画结束时显示它。
以下是在属性路径上创建关键动画的示例代码。
如果您想创建自己的路径动画,请确保路径中始终有相同数量的点。
It is possible to animate the mask change.
I prefer to use CAShapeLayer as the mask layer. It is very convenient to animate a mask change with the help of property path.
Before animate any change, dump the content of the source into an instance CGImageRef, and create a new layer for animation. Hide the original layer during the animation and show it when animation ends.
The following is a sample code for creating key animation on property path.
If you want to create your own path animation, make sure that there are always same number of points in the paths.
Swift 3+ 基于 Kekoa 的解决方案的答案:
Swift 3+ answer based on Kekoa's solution:
快速实现@stigi答案,我的遮罩层称为形状层
Swift implementation of @stigi answer, my mask layer is called shape Layer