如何围绕环的中心点绘制圆形按钮?
How to plot circular buttons around a central point in a ring?
我正试图在这样的环中绘制圆形按钮。
我有 6 个 UI 按钮,它们的角半径都是 360 度,我在 Swift 中试图做的是将它们均匀地围绕中心 button/point 绘制像上图一样。每个圆圈与其相邻圆圈的间距相等。实现此功能的最佳方式是什么?我应该创建一条贝塞尔曲线,然后使用数学来绘制该曲线周围的按钮,还是有其他建议的方法?
旁注是我不是在寻找任何类型的径向菜单,不需要动画。我只是想以上面的格式绘制我现有的 UI 按钮。
谢谢!
我建议使用 数学(三角函数) 计算距中心按钮的水平和垂直偏移量,然后使用布局锚点定位按钮。
这是一个独立的例子:
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
并且按钮将随之移动。
这里是模拟器中的运行:
你不需要贝塞尔曲线,只需一点计算。
我不是数学天才之类的,所以我拿了一个 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.
编码愉快!
我正试图在这样的环中绘制圆形按钮。
我有 6 个 UI 按钮,它们的角半径都是 360 度,我在 Swift 中试图做的是将它们均匀地围绕中心 button/point 绘制像上图一样。每个圆圈与其相邻圆圈的间距相等。实现此功能的最佳方式是什么?我应该创建一条贝塞尔曲线,然后使用数学来绘制该曲线周围的按钮,还是有其他建议的方法?
旁注是我不是在寻找任何类型的径向菜单,不需要动画。我只是想以上面的格式绘制我现有的 UI 按钮。
谢谢!
我建议使用 数学(三角函数) 计算距中心按钮的水平和垂直偏移量,然后使用布局锚点定位按钮。
这是一个独立的例子:
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
并且按钮将随之移动。
这里是模拟器中的运行:
你不需要贝塞尔曲线,只需一点计算。
我不是数学天才之类的,所以我拿了一个 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.
编码愉快!