Я хочу создать подобное меню,
.
Но не получаю идеальных центральных точек для пунктов меню (UIButton), я использую Stride(from:)
in getCirclePoints()
чтобы получить CGPoint для пунктов меню с равным интервалом от начального и конечного углов.
numberOfViews
переменная содержит количество пунктов меню, которые я хочу разместить.
Если numberOfViews = 5
тогда вывод будет
.
У кого-то есть идея лучше создать такое динамическое c меню или помочь мне в этом куске кода.
Спасибо.
class ViewController: UIViewController {
@IBOutlet weak var btnMenu: UIButton!
var numberOfViews: Int = 4
var arrPoints: [CGPoint] = []
var arrMenuItems = [UIButton]()
var menuFrame: CGRect!
var itemFrame: [CGRect] = []
var isMenuOpen = false
override func viewDidLoad() {
super.viewDidLoad()
prepareUI()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
}
extension ViewController {
@IBAction func btnMenuTapped(_ sender: UIButton) {
menu(open: isMenuOpen)
}
}
extension ViewController {
func prepareUI() {
createMenuItems()
storeFrame()
btnMenu.makeRounded(0, isFullyRounded: true)
menu(open: false, withDuration: 0.0001)
}
func createMenuItems() {
arrPoints = getCirclePoints(centerPoint: btnMenu.center, radius: (self.view.bounds.width/CGFloat(numberOfViews) + 25), n: numberOfViews)
for i in 0..<numberOfViews {
drawMenuItem(for: i)
}
}
func drawMenuItem(for index: Int) {
var menuItem: UIButton
let rect = CGRect(x: arrPoints[index].x, y: arrPoints[index].y, width: 50, height: 50)
menuItem = UIButton(frame: rect)
menuItem.makeRounded(0, isFullyRounded: true)
menuItem.backgroundColor = UIColor.randomColor
arrMenuItems.append(menuItem)
view.addSubview(menuItem)
}
func getCirclePoints(centerPoint point: CGPoint, radius: CGFloat, n: Int)->[CGPoint] {
let result: [CGPoint] = stride(from: -168, to: 12, by: Double(180 / n)).map {
let bearing = CGFloat($0) * .pi / 180
let x = point.x + radius * cos(bearing)
let y = point.y + radius * sin(bearing)
return CGPoint(x: x, y: y)
}
return result
}
func storeFrame() {
menuFrame = btnMenu.frame
}
func menu(open isOpen: Bool, withDuration duration: Double = 0.5) {
if isOpen {
self.view.bringSubviewToFront(self.btnMenu)
UIView.animate(withDuration: duration, animations: {
for element in self.arrMenuItems {
element.frame = self.menuFrame
}
}) { (completed) in
self.isMenuOpen = !self.isMenuOpen
}
}else {
UIView.animate(withDuration: duration, animations: {
for (index, element) in self.arrMenuItems.enumerated() {
element.frame = CGRect(x: self.arrPoints[index].x, y: self.arrPoints[index].y, width: element.frame.width, height: element.frame.height)
}
self.view.layoutIfNeeded()
}) { (completed) in
self.isMenuOpen = !self.isMenuOpen
}
}
}
}
extension UIButton {
func makeRounded(_ cornerRadius: CGFloat, isFullyRounded: Bool) {
if isFullyRounded {
self.layer.cornerRadius = self.frame.width / 2
}else {
self.layer.cornerRadius = cornerRadius
}
}
}
// MARK:- Color extension
extension UIColor {
// To get random color
static var randomColor: UIColor {
return UIColor(red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1), alpha: 1.0)
}
}