沿椭圆形UIBezierPath动画CAShapeLayer

时间:2019-08-14 14:55:32

标签: swift uibezierpath cashapelayer cakeyframeanimation

我正在尝试沿CAShapeLayerUIBezierPath设置动画。这在圆形路径情况下可以正常工作,但在使用椭圆形路径时却不能。动画确实发生了,但每次播放一轮都会暂停一小段时间,而无需我设置延迟。

更改大小和时间似乎并不能改善问题,但可以使暂停时间更长或更短。例如,在下面的动画中将持续时间设置为1,则暂停会变得非常短(这与沿路径的旋转速度加快一致)。

这是路径:

let ovalPath = UIBezierPath(ovalIn: CGRect(x: -25, y: -50, width: 50, height: 100))
ovalPath.apply(CGAffineTransform(rotationAngle: 45 * .pi / 180))
ovalPath.apply(CGAffineTransform(translationX: frame.size.width / 2, y: frame.size.height / 2))

具有ShapeLayer:

let ovalLayer = CAShapeLayer()
ovalLayer.strokeColor = UIColor.lightGray.cgColor
ovalLayer.fillColor = UIColor.clear.cgColor
ovalLayer.path = ovalPath.cgPath
view.layer.addSublayer(ovalLayer)

显示椭圆形路径,倾斜45度。这是我设置动画的方式:

let animation = CAKeyframeAnimation(keyPath: #keyPath(CALayer.position))
animation.duration = 5
animation.repeatCount = MAXFLOAT
animation.path = ovalPath.cgPath

最后是路径的形状:

let objectPath = UIBezierPath(arcCenter: CGPoint(x: 0 ,y: 0), radius: 50, startAngle: CGFloat(0), endAngle:CGFloat(Double.pi * 2), clockwise: true)
let objectLayer = CAShapeLayer()
objectLayer.path = objectPath.cgPath
objectLayer.strokeColor = UIColor.darkGray.cgColor
objectLayer.fillColor = UIColor.darkGray.cgColor
view.layer.addSublayer(objectLayer)
objectLayer.add(animation, forKey: nil)

我希望它无限循环而不会暂停(这在循环路径中完全一样)。我缺少明显的东西吗?

编辑:尝试使用timingFunction,如下所示:

animation.timingFunction = CAMediaTimingFunction(name: <CAMediaTimingFunctionName>)

例如:

animation.timingFunction = CAMediaTimingFunction(name: .default)

编辑2:

这是当前的样子。动画从右下角开始。两个椭圆的代码完全相同,除了动画持续时间(1秒与5秒)

enter image description here

1 个答案:

答案 0 :(得分:2)

这是一个解决方案(跳转只是gif动画结尾)。使用Xcode 11.4 / iOS 13.4进行了测试

demo

let animation = CAKeyframeAnimation(keyPath: #keyPath(CALayer.position))
animation.duration = 5
animation.repeatCount = .greatestFiniteMagnitude // just recommended by Apple
animation.path = ovalPath.cgPath
animation.calculationMode = .paced    // << required !!
相关问题