Search code examples
iosswiftuimenu

How to present UIMenu manually on a button tap?


I would like to present my UIMenu from UIButton when button is tapped. Because in the beginning I need to update children of UIMenu.

let menuButton: UIButton = {
    let button = UIButton()
    button.menu = UIMenu(title: "title")
    button.showsMenuAsPrimaryAction = true
    return button
}()

func setupView() {
    menuButton.rx.tap.bind {
        let action = UIAction(title: "title", image: nil, handler: { _ in })
        menuButton.menu.replacingChildren([action])
//            present menu, how?
    }.disposed(by: disposeBag)
}

Nothing happens here. My action for tap is registered with RxSwift. How can I do it to present the menu?


Solution

  • There is a need to add system .menuActionTriggered action:

    let menuButton: UIButton = {
        let button = UIButton()
        button.menu = UIMenu(title: "")
        button.showsMenuAsPrimaryAction = true
        return button
    }()
    
    menuButton.addAction(UIAction(title: "") { _ in
        menuButton.menu = UIMenu(title: "newtitle", children: [])
        // this block is called BEFORE new menu appear on the screen, and anything may be modified before presentation
    }, for: .menuActionTriggered)
    

    replacingChildren([action]) return a copy of new UIMenu which need to be assigned to .menu property again.