-2

I am trying to create a timer. I have a circle using UIBezierPath which I will animate to show the time remaining. This is the code that draws the shape and adds it to the view:

func drawBgShape() {
    bgShapeLayer.path = UIBezierPath(arcCenter: CGPoint(x: center.x , y: center.y), radius:
        bounds.width/2, startAngle: -.pi/2, endAngle: 1.5*.pi, clockwise: true).cgPath
    bgShapeLayer.strokeColor = UIColor.red.cgColor
    bgShapeLayer.fillColor = UIColor.clear.cgColor
    bgShapeLayer.lineWidth = 10
    layer.addSublayer(bgShapeLayer)
}

However, when the code is run, it looks like this;

Not in the centre

I have tried a number of ways to centre the progress bar but none of them seem to work. For example, using frame.height/2 doesn't have any effect.

How can I centre the progress bar?

Thanks.

EDIT: bgShapeLayer is defined like this:

let bgShapeLayer = CAShapeLayer()
Will Taylor
  • 511
  • 1
  • 6
  • 14
  • Everything depends on the frame and position of bgShapeLayer. But you have not shown that code. None of the code you’ve shown is meaningful in isolation. – matt Oct 23 '18 at 13:07
  • I have added how bgShapeLayer is defined. There is no other code that effects bgShapeLayer. – Will Taylor Oct 23 '18 at 13:15

1 Answers1

4

The issue is probably this phrase:

arcCenter: CGPoint(x: center.x , y: center.y)

A view center is where the view is located in its superview. That’s not what you want. You want the center of the view. Try this:

arcCenter: CGPoint(x: bounds.midX , y: bounds.midY)

However, it would be better if you gave your shape layer a frame, size, and position and did everything in terms of the shape layer (which is, after all, where the shape is being drawn). For example:

bgShapeLayer.frame = self.layer.bounds
self.layer.addSublayer(bgShapeLayer)
bgShapeLayer.path = UIBezierPath(
    arcCenter: CGPoint(x: bgShapeLayer.bounds.midX, y: bgShapeLayer.bounds.midY), 
    radius: bgShapeLayer.bounds.width/2, 
    startAngle: -.pi/2, endAngle: 1.5*.pi, clockwise: true).cgPath

That way we do not confuse the view coordinates and the layer coordinates, as your code does. To some extent you can get away with this because it happens that in this situation there is a general equivalence of the view internal coordinates, its layer internal coordinates, and the bgShapeLayer internal coordinates, but such confusion is not a good habit to get into. You should say what you mean rather than relying on a contingency.

matt
  • 515,959
  • 87
  • 875
  • 1,141