I wan't to draw a circle in the grey View but it is not perfectly centered and I can't understand why.
I get the center of my view (circleView) and put it in the circle's center then i had CAShapeLayers to the superview
let shapeLayer = CAShapeLayer()
let shapeLayer2 = CAShapeLayer()
let center = circleView.center
let height = circleView.frame.height
// First circle
let circularPath = UIBezierPath(arcCenter: center, radius: height/2-20 , startAngle: -CGFloat.pi / 2, endAngle: (2 * CGFloat.pi) - (CGFloat.pi / 2), clockwise: true)
shapeLayer.path = circularPath.cgPath
shapeLayer.lineWidth = 20
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeColor = UIColor(named: "color1")!.cgColor
shapeLayer.strokeEnd = 1
view.layer.addSublayer(shapeLayer)
// Second circle
let circularPath2 = UIBezierPath(arcCenter: center, radius: height/2-20, startAngle: -CGFloat.pi / 2, endAngle: (2 * CGFloat.pi) - (CGFloat.pi / 2), clockwise: true)
shapeLayer2.path = circularPath2.cgPath
shapeLayer2.lineWidth = 20
shapeLayer2.fillColor = UIColor.clear.cgColor
shapeLayer2.strokeColor = UIColor(named: "color")!.cgColor
shapeLayer2.strokeEnd = 0.5
view.layer.addSublayer(shapeLayer2)
But here is what i get
I tried to get center of my view like this :
CGPoint(x: circleView.bounds.midX, y: circleView.bounds.midY)
and tried to add the shapeLayer to my circleView rather than the superview but it's not working neither. Do you have any idea ?
The best way to manage layers is to subclass UIView
and set the sizes, path points, etc in layoutSubviews()
.
Here's a quick example based on your code (I don't know what your "color" or "color1" are, so I set them to green and systemGreen):
class CircleView: UIView {
private let shapeLayer = CAShapeLayer()
private let shapeLayer2 = CAShapeLayer()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
// set shape layer properties and add them as sublayers
shapeLayer.lineWidth = 20
shapeLayer.fillColor = UIColor.clear.cgColor
//shapeLayer.strokeColor = UIColor(named: "color1")!.cgColor
shapeLayer.strokeColor = UIColor.systemGreen.cgColor
shapeLayer.strokeEnd = 1
self.layer.addSublayer(shapeLayer)
shapeLayer2.lineWidth = 20
shapeLayer2.fillColor = UIColor.clear.cgColor
//shapeLayer2.strokeColor = UIColor(named: "color")!.cgColor
shapeLayer2.strokeColor = UIColor.green.cgColor
shapeLayer2.strokeEnd = 0.5
self.layer.addSublayer(shapeLayer2)
}
override func layoutSubviews() {
super.layoutSubviews()
let center = CGPoint(x: bounds.midX, y: bounds.midY)
let height = bounds.height
// we can use the same path for both layers
let circularPath = UIBezierPath(arcCenter: center,
radius: height * 0.5 - 20.0,
startAngle: -.pi * 0.5, // start at minus 90-degrees (12 o'clock)
endAngle: .pi * 1.5, // end at 270-degrees (also 12 o'clock)
clockwise: true)
shapeLayer.path = circularPath.cgPath
shapeLayer2.path = circularPath.cgPath
}
}
Now we add the view to a controller:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let circleView = CircleView()
circleView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(circleView)
NSLayoutConstraint.activate([
circleView.widthAnchor.constraint(equalToConstant: 300.0),
circleView.heightAnchor.constraint(equalTo: circleView.widthAnchor),
circleView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
circleView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
])
circleView.backgroundColor = .lightGray
}
}
and the result is: