【问题标题】:How to plot circular buttons around a central point in a ring? [duplicate]如何在环的中心点周围绘制圆形按钮? [复制]
【发布时间】:2019-01-17 10:40:10
【问题描述】:

我正在尝试在这样的环中绘制圆形按钮。

我有 6 个 UI 按钮,它们的角半径都是 360 度,我在 Swift 中尝试做的是将它们均匀地绘制在中心按钮/点周围,就像上图一样。每个圆圈与其邻居的间距相等。实现此功能的最佳方法是什么?我应该创建一条贝塞尔曲线,然后使用数学在所述曲线周围绘制按钮,还是您会建议其他方式?

附带说明,我不是在寻找任何类型的径向菜单,不需要动画。我只是想以上述格式绘制我现有的 UI 按钮。

谢谢!

【问题讨论】:

    标签: ios swift uibutton uibezierpath


    【解决方案1】:

    我建议使用 math (trigonometry) 计算距中心按钮的水平和垂直偏移量,然后使用布局锚来定位按钮。

    这是一个独立的例子:

    class ViewController: UIViewController {
    
        func createButton(size: CGFloat) -> UIButton {
            let button = UIButton(type: .custom)
            button.backgroundColor = .red
            button.translatesAutoresizingMaskIntoConstraints = false
            button.widthAnchor.constraint(equalToConstant: size).isActive = true
            button.heightAnchor.constraint(equalToConstant: size).isActive = true
            button.layer.cornerRadius = size / 2
    
            return button
        }
    
        func setUpButtons(count: Int, around center: UIView, radius: CGFloat) {
            // compute angular separation of each button
            let degrees = 360 / CGFloat(count)
    
            for i in 0 ..< count {
                let button = createButton(size: 50)
                self.view.addSubview(button)
    
                // use trig to compute offsets from center button
                let hOffset = radius * cos(CGFloat(i) * degrees * .pi / 180)
                let vOffset = radius * sin(CGFloat(i) * degrees * .pi / 180)
    
                // set new button's center relative to the center button's
                // center using centerX and centerY anchors and offsets
                button.centerXAnchor.constraint(equalTo: center.centerXAnchor, constant: hOffset).isActive = true
                button.centerYAnchor.constraint(equalTo: center.centerYAnchor, constant: vOffset).isActive = true
            }
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let centerButton = createButton(size: 50)
            self.view.addSubview(centerButton)
    
            // use anchors to place center button in the center of the screen
            centerButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
            centerButton.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
    
            setUpButtons(count: 6, around: centerButton, radius: 100)
        }
    
    }
    

    注意事项:

    • 如果不需要中心按钮,只需在self.view周围设置按钮即可:

      setupButtons(count: 6, around: self.view, radius: 100)
      

      或围绕任意点:

      let point = CGPoint(x: 180, y: 300)
      let centerView = UIView(frame: CGRect(origin: point, size: CGSize.zero))
      self.view.addSubview(centerView)
      setUpButtons(count: 6, around: centerView, radius: 140)
      
    • 使用UIView 作为中心而不是一个点更加灵活,因为您可以动态移动UIView,按钮也会随之移动。

    这里是在模拟器中运行的:

    【讨论】:

    • 这很好用,正是我想要的,我可以使用这种方法来增加内部按钮(或中心点)和按钮外环之间的间距吗?
    • radius 参数控制中心和圆环之间的间距。
    • 很好的答案...谢谢!!!
    • 正是我要找的东西。非常感谢。
    【解决方案2】:

    您不需要 bezierpath,只需进行一些计算即可。

    我不是数学天才或什么的,所以我拿了一个already answered question 并将其更改为我的需要。

    func place(buttons: [UIView], around center: CGPoint, radius: CGFloat) {
        var currentAngle: CGFloat = 0
        let buttonAngle: CGFloat = (CGFloat(360 / buttons.count)) * .pi / 180
    
        for button in buttons {
            let buttonCenter = CGPoint(x: center.x + cos(currentAngle) * radius, y: center.y + sin(currentAngle) * radius)
    
            // (1)
            //button.transform = CGAffineTransform(rotationAngle: currentAngle)
    
            // (2)
            //view.addSubview(button)
    
            button.center = buttonCenter
            currentAngle += buttonAngle
        }
    }
    

    使用 UIView 数组,让您更灵活。如果要从代码中添加按钮,只需取消注释 (1)。如果您希望按钮根据它们围绕中心的旋转进行旋转,请取消注释 (2)。

    顺便说一句,没有必要为圆形按钮添加 360 度圆角半径。请阅读文档here

    编码愉快!

    【讨论】:

      猜你喜欢
      • 2023-03-03
      • 1970-01-01
      • 2016-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多