Я хочу создать меню в форме полукруга, с N количеством пунктов меню - PullRequest
0 голосов
/ 18 февраля 2020

Я хочу создать подобное меню,

Menu image(with 4 items).

Но не получаю идеальных центральных точек для пунктов меню (UIButton), я использую Stride(from:) in getCirclePoints() чтобы получить CGPoint для пунктов меню с равным интервалом от начального и конечного углов.

numberOfViews переменная содержит количество пунктов меню, которые я хочу разместить.

Если numberOfViews = 5 тогда вывод будет

Menu with 5 items.

У кого-то есть идея лучше создать такое динамическое 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)
    }
}

Ответы [ 2 ]

1 голос
/ 18 февраля 2020

вы можете использовать фан-меню Библиотека для полукруглого меню

0 голосов
/ 18 февраля 2020

Для заданной позиции кнопки showMenu, которая показывает / сворачивает пункты меню при нажатии.

Предположим, у нас есть круг вокруг кнопки showMenu, где мы должны отображать пункты меню по окружности круга. Заданная позиция кнопки showMenu: (cx, xy) известна

получить положение пунктов меню, используя следующую формулу:

x = cx + r * cos(a) 
y = cy + r * sin(a)

где r - радиус окружности, (cx, cy) центр showMenu и угол = (90) / numberofMenu

Для заданного набора точек, выведенных из формулы для каждой кнопки меню, добавьте параметры кнопок меню и анимируйте соответственно.

...