iosswiftcore-animationuibezierpath

UIBezierPath CAAnimation finishes too fast when startAngle changed


This code will draw a circle at 3'oclock. The duration is set to 10 seconds, and it visually lasts 10 seconds. However, I want the starting angle to appear at 12 o'clock, instead of 3 o'clock. If I change the start angle to -(.pi / 2), the code draws the circle from the 12 o'clock position, but visually finishes in about 8 seconds, instead of the specified 10 seconds? I've seen fixes for changing the animation.toValue to a lower number (see comment in code), but why does this need to be done?

let path = UIBezierPath(arcCenter: center, radius: 90, startAngle: 0, endAngle: .pi * 2, clockwise: true)
        
introAnimationLayer1 = CAShapeLayer()
introAnimationLayer1?.frame = animationView!.frame
introAnimationLayer1?.position = mainAnimationLayerPosition
introAnimationLayer1?.path = path.cgPath
introAnimationLayer1?.fillColor = UIColor.clear.cgColor
introAnimationLayer1?.lineCap = CAShapeLayerLineCap.square
introAnimationLayer1?.strokeColor = UIColor.red.cgColor
introAnimationLayer1?.lineWidth = 10
introAnimationLayer1?.fillColor = UIColor.clear.cgColor
introAnimationLayer1?.strokeStart = 0   
mainAnimationLayer.addSublayer(introAnimationLayer1!)
...
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = 10
animation.timingFunction = CAMediaTimingFunction(name: .linear)
animation.fromValue = 0
animation.toValue = 1 // Changing this to 0.795 will make the animation complete in the expected duration
animation.fillMode = .forwards
animation.isRemovedOnCompletion = false
animation.delegate = self
introAnimationLayer1.add(animation, forKey: "startingAnimation1")

Solution

  • If you change the start angle to -.pi/2 but leave the end angle at 2*.pi then you are drawing 1-1/4 circles in 10 seconds. So it will look like the circle is completing in 8 seconds. You can't see the remaining 2 seconds being used to draw the extra, and unwanted, extra 1/4 circle.

    Change the end angle to 3*.pi/2 so the full 10 seconds are only used to draw 1 circle instead of 1-1/4 circles.