ios - 在圆形路径中对线形 CAShapeLayer 进行动画处理

标签 ios swift cashapelayer cabasicanimation

我正在尝试沿着圆形路径为我的线形 CAShapeLayer 制作动画。我创建了线条图层的初始路径和最终路径,并将它们添加到 CABasicAnimation 的 from 和 to 值中。

但是动画并不是我所期望的。我被困在这里已经两天了。

func getAllLayers() -> [CALayer] 

   {

    var layers = []

    let pointerEndPoint = CGPoint(x: xPointOfPointer , y: yPointOfPointer)  // Final end point of pointer
    let radius = 5

    let pointerFinalPath = UIBezierPath()
    pointerFinalPath.addArc(withCenter: circleCenter, radius: radius, startAngle: 0, endAngle:2 * CGFloat.pi, clockwise: false)
    pointerFinalPath.move(to: circleCenter)
    pointerFinalPath.addLine(to: endPoint)
    pointerFinalPath.close()

    let pointerPathLayer = CAShapeLayer()
    pointerPathLayer.path = pointerFinalPath.cgPath
    pointerPathLayer.lineWidth = 2
    pointerPathLayer.fillColor = UIColor.black.cgColor
    pointerPathLayer.strokeColor = UIColor.black.cgColor
    layers.append(pointerPathLayer)

    let pointerInitialBezierPath = UIBezierPath()
    pointerInitialBezierPath.addArc(withCenter: circleCenter, radius: radius,startAngle: 0 , endAngle: 2 * CGFloat.pi , clockwise: false)
    pointerInitialBezierPath.move(to: circleCenter)
    pointerInitialBezierPath.addLine(to: CGPoint(x: circleCenter.x - 50 , y: centerY))
    pointerInitialBezierPath.close()


    let pointerInitialCGPath = pointerInitialBezierPath.cgPath
    let pointerFinalCGPath = pointerFinalPath.cgPath


                    // Pointer Animation
    let pointerAnimation = CABasicAnimation(keyPath: #keyPath(CAShapeLayer.path))
     pointerAnimation.fromValue = pointerInitialCGPath
     pointerAnimation.toValue = pointerFinalCGPath
      pointerAnimation.duration = 0.5
      pointerAnimation.isCumulative = true
      pointerPathLayer.add(pointerAnimation, forKey: "Animation")

return layers
}

在 Stack over flow 中搜索解决方案,但找不到我的错误。我希望我的动画像时钟的指针一样移动。

My Animation

请注意,针的长度随着动画的进行而变化。我希望它保持恒定的长度,只希望改变针的角度。我将非常感谢任何帮助。

编辑1:如果我尝试transform.rotation动画,我会得到针旋转,但它发生在错误的中心点周围。

      // Pointer Animation

            let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
            rotateAnimation.fromValue = 0.0
            rotateAnimation.toValue = angleOfActualValueinRad
            rotateAnimation.duration = 2.0
            pointerPathLayer.add(rotateAnimation, forKey: "Animation")

Roatation Animation

编辑 2:使用此链接查找我的 github 项目。 Animation Issue

最佳答案

您无法使用 UIBezierPath 实现速度计动画。 你需要将线变换成你想要的任何角度。 请引用以下我为解决您的问题而编写的旋转代码。

let circleCenter = CGPoint(x: 150.0, y: 150.0)

let startPoint = CGPoint(x: 100, y: 150.0)
    // Start Path
    let pointerStartPath = UIBezierPath()
    pointerStartPath.move(to: circleCenter)
    pointerStartPath.addLine(to: startPoint)
    pointerStartPath.close()

    let pointerPathLayer = CAShapeLayer()
    pointerPathLayer.frame = CGRect(x: 0, y:0, width: 300, height: 300)
    pointerPathLayer.path = pointerStartPath.cgPath
    pointerPathLayer.lineWidth = 2
    pointerPathLayer.fillColor = UIColor.green.cgColor
    pointerPathLayer.strokeColor = UIColor.black.cgColor
    self.view.layer.addSublayer(pointerPathLayer)

// New : Set Anchor point
pointerPathLayer.anchorPoint = CGPoint(x: 0.5, y: 0.5)

    let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
    rotateAnimation.fromValue = 0.0
    rotateAnimation.toValue = CGFloat.pi * 2.0
    rotateAnimation.duration = 2.0
    pointerPathLayer.add(rotateAnimation, forKey: "Animation")

使用此代码,可以实现360度旋转。

关于ios - 在圆形路径中对线形 CAShapeLayer 进行动画处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57157586/

相关文章:

iOS: AVQueuePlayer/AVPlayerItem 'An AVPlayerItem can occupy only one position in a player' s queue at a time.'

objective-c - 当手放在 iPad 屏幕上时,如何仅检测一次触摸?

iOS estimatedRowHeight 不适用于 plus 设备

ios - 如何使用 swift 等待登录 View 的 api 响应值

swift - 两点之间的正弦波 UIBezierPath

iphone - CAShapeLayer 上的 CAGradientLayer SetMask 使应用程序崩溃

ios - 限制和缩放 UITextField 中文本的大小

ios - 实现 UIScrollView 时遇到问题

ios - 移除按住 UIButton 时的阴影

ios - 如何旋转CAShapeLayer对象?