CAShapeLayer 특정 뷰의 중심에 맞추기

let circlePath = UIBezierPath(arcCenter: completeButton.center, radius: completeButton.frame.width/2, startAngle: 0, endAngle: .pi * 2, clockwise: true)
let shape = CAShapeLayer()
shape.path = circlePath.cgPath
shape.fillColor = UIColor.red.cgColor
completeButton.layer.addSublayer(shape)

UIBezierPath로 원을 completeButton과 같은 크기와 위치에 그리려고 했는데, center가 일치하지 않는 문제가 발생.

 

원인

UIView의 center는 슈퍼뷰를 기준으로 해당 뷰의 center를 반환 해줌. 즉 해당 center는 슈퍼뷰를 대상으로 한 center임. 그런데 button에 layer를 add해서 해당 레이어는 슈퍼뷰를 대상으로 한 center를 가지고 button의 layer에 그리게 되므로 이런 문제가 발생.

 

해결

해당 button의 bounds를 frame으로 가지고 있는 Layer를 하나 추가 한 후, 해당 레이어를 기준으로 원을 그리는 식으로 해결

let trackLayer = CAShapeLayer()
trackLayer.frame = completeButton.bounds
completeButtonRingLayer = CAShapeLayer()
guard let completeButtonRingLayer = completeButtonRingLayer else { return }
completeButtonContainerView.layer.addSublayer(completeButtonRingLayer)
completeButtonRingLayer.path = UIBezierPath(arcCenter: trackLayer.position, radius: completeButton.frame.width/2+2, startAngle: .pi * (3/2), endAngle: .pi * (7/2), clockwise: true).cgPath

 

 

출처: https://stackoverflow.com/questions/59149674/center-of-uiview-not-centered