ios - 为什么我不能为作为 CAAnimationGroup 一部分的图层子图层的路径设置动画,但我可以为组中的其他属性设置动画?
问题描述
感谢@matt,我不久前了解到可以在CAAnimationGroup
. 诀窍是为子层添加名称。
有关该技术的讨论,请参见 Matt 在此线程中的回答,以及我为测试它而编写的一个工作示例。
然后将动画组添加到父层,并在影响父层的子层的动画中,使用keyPath
将子层引用为父层的命名子层的值创建这些子层动画。
所以如果我有 CAShapeLayer parentLayer
,那也有一个名为“sublayer”的子层,
let parentLayer = CAShapeLayer()
let sublayer = CAShapeLayer()
sublayer.name = "sublayer"
parentLayer.addSublayer(sublayer)
我想创建一个动画组,同时为父层和子层的属性设置动画,该代码可能如下所示:
let animationGroup = CAAnimationGroup()
animationGroup.duration = animationDuration
let parentLayerAnimation = CABasicAnimation(keyPath: "path")
parentLayerAnimation.duration = animationDuration
parentLayerAnimation.fromValue = parentLayer.path
parentLayerAnimation.toValue = newPath
let sublayerAnimation = CABasicAnimation(keyPath: "sublayers.sublayer.path")
sublayerAnimation.duration = animationDuration
sublayerAnimation.fromValue = subLayer.path
sublayerAnimation.toValue = newSublayerPath
let animationGroup = CAAnimationGroup()
animationGroup.duration = animationDuration
animationGroup.animations = [parentLayerAnimation, sublayerAnimation]
parentLayer.add(animationGroup, forKey: nil)
上面的代码不起作用。问题似乎特别在于尝试为子图层的路径设置动画。如果我改为动画子层的旋转,使用如下代码:
let sublayerRotationAnimation = CABasicAnimation(keyPath: "sublayers.sublayer.transform.rotation.z")
sublayerRotationAnimation.duration = animationDuration
sublayerRotationAnimation.fromValue = 0
sublayerRotationAnimation.toValue = CGFloat.pi
并将其添加sublayerRotationAnimation
到动画组中,这样就可以了。
如果我尝试为子图层的路径设置动画,似乎会出现问题。动画其他属性的作品。
(如果我将子图层动画的关键路径更改为“路径”并将动画直接添加到子图层,那也可以。)
我追求的效果是这样的:
(动画成弧线的黑色插入符号是父层,带点的红线是子层bezierIllustrationLayer
。)
我在 Github 上有一个工作项目的一个分支,它说明了这个问题:
该项目的主要分支只是将单独的动画提交给图层和子图层,并且可以正常工作。
该分支中尝试添加动画组的代码位于文件 CaretToArcView.swift 中:
let pathAnimation = CABasicAnimation(keyPath: "path")
pathAnimation.duration = animationDuration
pathAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
pathAnimation.fromValue = layer.path
pathAnimation.toValue = path.cgPath
// This animation does not work when added to an animation group applied to the parent layer of the bezierIllustrationLayer
let bezierPathAnimation = CABasicAnimation(keyPath: "sublayers.bezierillustrationlayer.path")
bezierPathAnimation.duration = animationDuration
bezierPathAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
bezierPathAnimation.fromValue = bezierIllustrationLayer.path
bezierPathAnimation.toValue = illustrationPath.cgPath
//If I add this rotation animation to the animation group, it works
//let rotationAnimation = CABasicAnimation(keyPath: "sublayers.bezierillustrationlayer.transform.rotation.z")
//rotationAnimation.duration = 1.0
//rotationAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
//rotationAnimation.fromValue = 0
//rotationAnimation.toValue = CGFloat.pi * 2
let animationGroup = CAAnimationGroup()
animationGroup.duration = animationDuration
animationGroup.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
animationGroup.animations = [pathAnimation, bezierPathAnimation]
layer.add(animationGroup, forKey: nil)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
layer.path = path.cgPath
self.bezierIllustrationLayer.path = illustrationPath.cgPath
}
据我所知,这是 CAAnimationGroup 中的一个错误。如果我将它直接应用于子层(在适当地更改 keyPath 之后),则相同的动画可以工作。不同属性的动画,如动画组中子图层的transform.rotation.z
作品。它只是为失败的子层路径设置动画。
有没有其他人遇到过这种情况,您有解决方案吗?马特? 我认为你是这里的 CAAnimation 专家。你能帮我吗?
解决方案
推荐阅读
- flutter - 使用 VsCode 的 Flutter 项目启动问题
- java - 无法使用“Google Play 服务”,请在非 GSM 手机中添加捆绑 MLKit 扫描后尝试允许权限错误
- javascript - 使用无法正常工作的 JavaScript 函数更新数据
- reactjs - 从 reactsJS 中的 iframe 捕获 html2canvas
- python - 使用请求和漂亮的汤访问网页
- python - Selenium chrome 不加载特定网站的图像
- laravel - 获取子类别下的产品数量以及子类别中主要类别的总数
- download - 如何使用启用下载列表器将驱动器链接插入到 android studio 项目
- ms-wopi - 在 windows server 2012 r2 中配置 WOPI 集成后 Excel 未打开
- payumoney - 如何修复 wordpress 中 Payumoney 不正确的哈希参数错误