Ios 如何沿UIBezierPath仅为整个CALayer动画的一部分设置动画?

Ios 如何沿UIBezierPath仅为整个CALayer动画的一部分设置动画?,ios,caanimation,cakeyframeanimation,Ios,Caanimation,Cakeyframeanimation,我设法沿UIBezier路径设置CALayer的动画 我试图实现的是仅对路径的一部分设置动画,例如,仅对路径的25%设置动画,层保持在该位置(25%) 这样做的方法是什么?这是我的代码,它总是设置完整路径的动画 let aPath = UIBizierPath(CGPath: somePath) let anim = CAKeyframeAnimation(keyPath: "position") anim.path = aPath.CGPath anim.rotationMode = kCAA

我设法沿UIBezier路径设置CALayer的动画

我试图实现的是仅对路径的一部分设置动画,例如,仅对路径的25%设置动画,层保持在该位置(25%)

这样做的方法是什么?这是我的代码,它总是设置完整路径的动画

let aPath = UIBizierPath(CGPath: somePath)
let anim = CAKeyframeAnimation(keyPath: "position")
anim.path = aPath.CGPath
anim.rotationMode = kCAAnimationRotateAuto
anim.repeatCount = 1
anim.fillMode = kCAFillModeForwards
anim.removedOnCompletion = false
anim.duration = 3.0
anim.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)

ticker.addAnimation(anim, forKey: "animate_ticker")

简单更改一个属性:

anim.repeatCount = 0.25    
下面是一个示例,您可以学习如何对动画进行更细粒度的控制

附加:
1.要实现您想要的,最接近的方法是拥有25%的子路径,下面是一些

2.如果您能忍受速度差,请使用上述方法,并在动画结束时将位置设置回原位:

ticker.position = ticker.presentationLayer().position

您是否尝试设置fromValuetoValue属性?如果将fromValue设置为0.0并将toValue设置为0.25

则该功能应能正常工作,不仅
CGPath
不透明,而且
CAAnimation
不支持任何正在进行的动画更新或通知(即启动后但完成前)。唯一涉及的实体是动画本身和它应用到的
CALayer
-s

因此,选择是:

(有些选项听起来可能太吓人了,但事实并非如此,所以我做了一个示例项目,见下文)

重复计数 正如wj2061所提到的,您可以调整动画的
repeatCount
。缺点是它将动画0.25的动画时间,而不是0.25的路径

现金支付者 如果您可以用
CAShapeLayer
段来表示您的
ticker
,那么您可以设置
strokeStart
strokeEnd
的动画,使其看起来像是段沿路径移动

聪明的重复计数 您可以计算动画将在路径的0.25处停止的
repeatCount

  • 抓取一些贝塞尔库
  • 使用
    getControlPointAtIndex:
  • 求解bezier以获得其“进度值”(通常命名为
    t
    ),bezier的“y”值将与您的“所需进度”(0.25)匹配
  • 计算该
    t
    的贝塞尔'x'值-这是您需要的
    repeatCount
    的精确值
用动画制作动画,全靠你自己 有点高级

  • 抓取一些贝塞尔库
  • 创建具有动态属性的自定义CALayer子类,比如说
    rideProgress
  • 添加bezier路径(来自bezier库,而不是CGPath)和子层(例如,
    rideLayer
    )的合成属性以设置动画
  • 覆盖
    needsDisplayForKey:
    用于
    rideProgress
    键和
    initWithLayer:
    用于所有引入的属性,但使用
    self.rideLayer?.presentationLayer()
    而不是复制
    rideLayer
  • 覆盖其中一个:
    drawInContext:
    并在其中绘制所需内容;或者(更好)
    display
    ,在
    display
    中从
    presentationLayer
    检索当前
    rideProgress
    值并更新子层,然后调用super。无论哪种方式,都可以使用bezier lib根据当前
    rideProgress
    值计算子层的位置和旋转
  • 在设置任何层的任何可设置动画的属性之前,不要忘记
    CATransaction.setDisableActions(true)
  • 最后,在
    rideProgress
    属性上使用任何类型的动画或隐式动画
分割路径 再一次,我的建议是。您可以分割路径,使一半中的一个表示原始路径的0.25


是除“分割路径”之外的上述所有内容的示例实现。我没有对这段代码进行任何现场测试,这只是一个可行的概念。代码7.3.1,Swift



使用的材质:,

我遇到了同一个问题,我想为路径的绘制制作动画,但只占其中的一部分

我最后做的是将层的strokeStart和strokeEnd设置为与动画相同的浮点值

因此,在您的示例中,尝试设置
anim.fromValue=0.0f
、anim.toValue=0.6f以及
ticker.strokeStart=0.0f
ticker.strokeEnd=0.6f


这只成功地绘制了60%的路径,并为其设置了动画

这样做的问题是,动画不会停止路径的1/4,而只停止动画路径的1/4。因此,使用
kCamediatiming函数easeAseOut
计时功能和
repeatCount
的0.25,动画将比预期的更快停止。此外,计时功能仍将应用于整个动画的持续时间,因此它似乎会加速,然后突然停止,这可能是OP想要的,也可能不是OP想要的。@originaluser2,您是对的。我发现动画并没有完全停止在我认为它会停止的地方,所以这就解释了它!谢谢我在寻找1/4的路径,而不是动画。
fromValue
toValue
是在
CABasicAnimation
中引入的,它不是
CAKeyframeAnimation
的超类。我不记得确切的原因,但这不起作用。(我不是投反对票的人)