如何在UIView上正确地设置圆形周围的对象

15

我写了一些代码,用于将对象放置在自定义视图中心的圆周上,但它们没有完全围绕圆周分布。我不知道代码的哪里出了问题。

enter image description here

这是代码:

func createObjectsAroundCircle() {

    let center = CGPointMake(bounds.width/2 ,bounds.height/2)
    let radius : CGFloat = 100
    let count = 20

    var angle = CGFloat(2 * M_PI)
    let step = CGFloat(2 * M_PI) / CGFloat(count)

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

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

    shapeLayer.fillColor = UIColor.clearColor().CGColor
    shapeLayer.strokeColor = UIColor.redColor().CGColor
    shapeLayer.lineWidth = 3.0

    self.layer.addSublayer(shapeLayer)

    // set objects around circle
    for var index = 0; index < count ; index++ {
        let x = cos(angle) * radius + center.x
        let y = sin(angle) * radius + center.y

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

        self.addSubview(label)
        angle += step 
    }
}

1
标签框架的原点是其左上角。这就是为什么您的标签文本在右下象限外部显示,在左上象限内部显示。 - user4151918
1
在设置临时框架后,将那些x和y点简单地设置为标签中心。 - Ravi
@PetahChristiani 谢谢,我真的忘了那个。 - Masa S-AiYa
2个回答

16

你的代码运行正常,只是计算逻辑有误。你应该尝试设置label.center而不是label.frame.origin,或者

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

在更改标签的框架或设置标签的中心位置之前,请记得先调用sizeToFit()方法。祝好运!


1
下载示例代码并查看。 - Pawan Sharma

3

Swift 5

为了方便起见,Masa S-AiYa的问题逻辑和Fahri Azimov的答案已经合并:

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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接