3

I have a function to draw an animated circle as a processing bar. I can get it animated from the bottom of the circle. However, I would like to change the start point to the top of the circle.

I attached my code below:

func animateProgressView(_finishPoint:CGFloat, _stringShowAtEnd: String) {
    progressLabel.text = "Rating..."
    progressLayer.strokeEnd = 0.0
    
    let animation = CABasicAnimation(keyPath: "strokeEnd")
    animation.fromValue = CGFloat(0.0)
    animation.toValue = CGFloat(_finishPoint)
    animation.duration = 2.0
    animation.delegate = self
    animation.removedOnCompletion = false
    animation.additive = true
    animation.fillMode = kCAFillModeForwards
    progressLayer.addAnimation(animation, forKey: "strokeEnd")
    stringShowAtEnd=_stringShowAtEnd
}

What I have quickly tried:

  • changed fromValue and toValue to 0.5 and 1.0. //didn't work
  • changed the fillMode to kCAFillModeBackwards. //didn't work
  • changed the keyPath and forKey to "strokeStart" //didn't work

I haven't spent too much time on reading the official documents.

Anyone can provide a quick answer how can I change the start point to the top like the picture shown below?

enter image description here


Solution:

Thank "rob mayoff". He point me out I should post the path creation function, which I didn't notice and recognize. I solved the problem by modifying the angles of both startAngle and endAngle.

I attached the code below. I hope it will be helpful for everyone who has the similar issue.

private func createProgressLayer() {
    //let startAngle = CGFloat(M_PI_2)  //old angle, Pi/2=90 degrees ,started from the bottom
    //let endAngle = CGFloat(M_PI * 2 + M_PI_2) //old angle,2*Pi+Pi/2=360 + 90 degrees ,end at the bottom

    let startAngle = CGFloat(M_PI_2*3)  //new angle, (Pi/2)*3=90*3 degrees ,starts from the top

    
    let endAngle = CGFloat(M_PI * 2 + M_PI_2*3) //new angle, 2*Pi+(Pi/2)*3=360 + 90*3 degrees ,ends at the top
    
    
    let centerPoint = CGPointMake(CGRectGetWidth(frame)/2 , CGRectGetHeight(frame)/2)
    
    var gradientMaskLayer = gradientMask()
    progressLayer.path = UIBezierPath(arcCenter:centerPoint, radius: CGRectGetWidth(frame)/2 - 30.0, startAngle:startAngle, endAngle:endAngle, clockwise: true).CGPath
    progressLayer.backgroundColor = UIColor.clearColor().CGColor
    progressLayer.fillColor = nil
    progressLayer.strokeColor = UIColor.blackColor().CGColor
    progressLayer.lineWidth = 10.0
    progressLayer.strokeStart = 0.0
    progressLayer.strokeEnd = 0.0
    
    gradientMaskLayer.mask = progressLayer
    layer.addSublayer(gradientMaskLayer)
}
Community
  • 1
  • 1
Ares Li
  • 603
  • 1
  • 7
  • 19
  • 3
    Edit your question to include the code that creates the path you're animating. – rob mayoff Aug 04 '15 at 06:09
  • similar question in Objective-C here:http://stackoverflow.com/a/9143116/411604 – antonio081014 Aug 04 '15 at 06:11
  • 1
    Not really. That question was about what happens when the animation ends. This question is about what happens during the animation, and the problem is that the path starts in the wrong place. The path needs to be constructed differently. – rob mayoff Aug 04 '15 at 06:12
  • Thanks for every answer, @robmayoff. Your answer is a good hint to me. I didn't notice there was a part of code that does the path creation. The problem has been solved now. I will also update my question posted soon. Thanks again. – Ares Li Aug 04 '15 at 15:43

1 Answers1

1

You're creating the path so that the start point is at the bottom. You need to create the path so that the start point is at the top.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848