How to set objects around circle correctly on UIView

Swift 5

For convenience purposes, both Masa S-AiYa question logic + Fahri Azimov answer have been combined:

let center = CGPoint(x: bounds.size.width/2, y: bounds.size.width/2)
let radius: CGFloat = 100
let count = 20

let pi = Double.pi
var angle = CGFloat(2 * pi)
let step = CGFloat(2 *  pi) / CGFloat(count)

let circlePath = UIBezierPath(arcCenter: center, radius: radius, startAngle: CGFloat(0), endAngle:CGFloat(pi * 2), clockwise: true)

let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath

shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.lineWidth = 3.0

layer.addSublayer(shapeLayer)

let font = UIFont(name: "Arial", size: 20)

// Set objects around the circle
for index in 0..<count {
    let label = UILabel()
    label.text = "\(index)"
    label.font = font
    label.textColor = .black
    // Remember to call 'sizeToFit()' before changing 'frame' or setting 'center' of the label!
    label.sizeToFit()
    
    // Position
    let x = cos(angle) * radius + center.x
    let y = sin(angle) * radius + center.y
    let midX = label.frame.x + label.frame.width / 2
    let mixY = label.frame.y + label.frame.height / 2
    
    label.frame.origin.x = x - midX
    label.frame.origin.y = y - mixY
    
    addSubview(label)
    angle += step
}

Your code is working alright, just calculation logic is wrong. You should try to set label.center instead of label.frame.origin, or

let label = UILabel()
label.text = "\(index)"
label.font = UIFont(name: "Arial", size: 20)
label.textColor = UIColor.blackColor()
label.sizeToFit()
label.frame.origin.x = x - label.frame.midX
label.frame.origin.y = y - label.frame.midY

Remember to sizeToFit() before changing frame or setting center of the label. Good Luck!

Tags:

Ios

Swift