【问题标题】:Animating a CAShapeLayer along an oval UIBezierPath沿椭圆形 UIBezierPath 为 CAShapeLayer 设置动画
【发布时间】:2019-08-14 14:55:32
【问题描述】:

我正在尝试为 CAShapeLayer 沿 UIBezierPath 设置动画。这在圆形路径情况下效果很好,但在我使用椭圆形路径时却不行。动画确实发生了,但每次播放一圈都会暂停一小段时间,我没有设置延迟。

更改大小和时间似乎并没有改善问题,但会使暂停时间更长/更短。例如,在下面的动画中将duration设置为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 秒)

【问题讨论】:

  • 您的动画没有计时功能,因此它可能默认为缓入缓出。因此暂停。
  • 谢谢,我刚刚尝试过,但没有看到任何变化。我已经编辑了我的帖子以包含timingFunction
  • 马特,我也有同样的想法,但是当他的路径是圆形而不是椭圆形时,为什么他看不到同样的东西呢?
  • 致 OP:带有缓入缓出时间的重复动画不会完全暂停 - 它会滑到停止,然后滑回开始。效果与暂停有点不同,暂停会“突然停止”然后重新开始运动。通过观看动画应该很容易区分。
  • 您添加到问题中的代码无效。这是创建计时函数的模板。您在项目中放入的实际代码是什么?

标签: swift uibezierpath cashapelayer cakeyframeanimation


【解决方案1】:

这里有一个解决方案(跳转只是gif动画结束)。使用 Xcode 11.4 / iOS 13.4 测试

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 !!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 2020-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多