I'm trying to render a shape in the center of Circle, a custom subclass of UIView (first snippet). Then I'm adding the Circle as a subview in my VC and adding constraints (second snippet).
When height and width is constrained, the rendered shape has its center (undesirably) in the top left corner of the Circle view (picture bellow). When only X and Y of the Circle view are constrained, the shape is in center as expected.
Why does this happen and what do I do to be able to constrain Circle as I please but still have the shape render in the center of Circle ? Thanks.
Circle:
class Circle: UIView {
func render(){
let shapeLayer = CAShapeLayer()
let center = self.center
let endAngle = 2 * CGFloat.pi
let circularPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: 0, endAngle: endAngle, clockwise: true)
shapeLayer.path = circularPath.cgPath
self.layer.addSublayer(shapeLayer)
}
}
VC:
class VC: UIViewController {
let circle = Circle()
override func viewDidLoad() {
super.viewDidLoad()
configure()
circle.render()
}
func configure(){
view.backgroundColor = .white
view.addSubview(progressCircle)
progressCircle.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
progressCircle.centerYAnchor.constraint(equalTo: view.centerYAnchor),
progressCircle.centerXAnchor.constraint(equalTo: view.centerXAnchor),
progressCircle.heightAnchor.constraint(equalToConstant: 200),
progressCircle.widthAnchor.constraint(equalToConstant: 200)
])
}
}
Result:
Here is fixed view (tested with Xcode 11.4 / Playground)
class Circle: UIView {
let shapeLayer = CAShapeLayer()
override func layoutSubviews() {
super.layoutSubviews()
shapeLayer.position = CGPoint(x: self.bounds.midX, y: self.bounds.midY)
}
func render(){
let center = self.center
let endAngle = 2 * CGFloat.pi
let circularPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: 0, endAngle: endAngle, clockwise: true)
shapeLayer.path = circularPath.cgPath
self.layer.addSublayer(shapeLayer)
}
}