围绕 Circle 的 CABasicAnimation 走得太远了

CABasicAnimation around Circle goes too Far

我希望在圆圈上添加动画外层以显示进度。我下面所拥有的能够做到这一点;然而,外部填充的结束动画太过分了。在我的示例中,我希望它从 12:00 位置移动到 6:00 位置或绕圆的 50%。在实践中,它会到达 8:00 位置。

class CircleView: UIView {

private let progressLayer = CAShapeLayer()
private var progressColor:UIColor!

required convenience init(progressColor:UIColor) {
    self.init(frame:.zero)
    self.progressColor = progressColor
}

override init(frame: CGRect) {
    super.init(frame: frame)

    self.translatesAutoresizingMaskIntoConstraints = false
}

required init?(coder: NSCoder) {
    super.init(coder: coder)
}

override func draw(_ rect: CGRect) {
    setup()
}

private func setup() {
    let circleLayer = CAShapeLayer()

    let center = CGPoint(x: self.bounds.size.width / 2, y: self.bounds.size.height / 2)
    let path = UIBezierPath(arcCenter: center, radius: self.frame.width / 2, startAngle: -CGFloat.pi / 2, endAngle: CGFloat.pi * 2, clockwise: true)
    circleLayer.path = path.cgPath
    circleLayer.strokeColor = UIColor.gray.cgColor
    circleLayer.fillColor = UIColor.white.cgColor
    circleLayer.lineCap = CAShapeLayerLineCap.round
    circleLayer.lineWidth = 20
    circleLayer.masksToBounds = false
    self.layer.addSublayer(circleLayer)

    progressLayer.path = path.cgPath
    progressLayer.strokeColor = progressColor.cgColor
    progressLayer.fillColor = UIColor.clear.cgColor
    progressLayer.lineCap = CAShapeLayerLineCap.round
    progressLayer.lineWidth = 20

    circleLayer.addSublayer(progressLayer)
}

func animateProgress(percentComplete:Double) {
    let progressAnimation = CABasicAnimation(keyPath: "strokeEnd")

    progressAnimation.fromValue = 0
    progressAnimation.toValue = 0.5
    progressAnimation.duration = 2
    progressAnimation.fillMode = .forwards
    progressAnimation.isRemovedOnCompletion = false

    progressLayer.add(progressAnimation, forKey: "strokeEnd")
}

如果我将上面的行更改为 progressAnimation.toValue = 0.4,它将显示我正在寻找的 12-6。我不明白为什么会是 0.4 而不是 0.5?

固定角度就可以了

let path = UIBezierPath(arcCenter: center, radius: self.frame.width / 2, startAngle: -CGFloat.pi / 2, endAngle: CGFloat.pi * 2, clockwise: true)

let path = UIBezierPath(arcCenter: center, radius: self.frame.width / 2, startAngle: -CGFloat.pi / 2, endAngle: 1.5 * CGFloat.pi, clockwise: true)

圆是 2 * CGFloat.pi,不是 2.5 * CGFloat.pi

startAngle: -CGFloat.pi / 2, endAngle: CGFloat.pi * 22.5 * CGFloat.pi

2 * CGFloat.pi * 0.5 等于 2.5 * CGFloat.pi * 0.4