5

I have the following code that generates a context menu when a user taps on a uibarbutton in a navigation bar:

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .systemGreen
        title = "Hello"
        
        let scribbleAction =  UIAction(title: "Scribble", image: UIImage(systemName: "scribble"), state: .on, handler: { (_) in })
        let textAction =  UIAction(title: "Typing", image: UIImage(systemName: "textformat"), state: .off, handler: { (_) in })
        
        let clockAction = UIAction(title: "Show Clock", image: UIImage(systemName: "clock"), state: .off, handler: { (_) in })
        let calendarAction = UIAction(title: "Date Last Used", image: UIImage(systemName: "calendar"), state: .off, handler: { (_) in })
        
        var showAsActions: [UIAction] {
            return [
                clockAction, calendarAction
            ]
        }
        
        var showAsMenu : UIMenu {
            return UIMenu(title: "Show As", image: UIImage(systemName: "questionmark.circle.fill"), identifier: .none, children: showAsActions)
        }
    
        let menu = UIMenu(title: "",
                          image: nil,
                          identifier: nil,
                          options: [],
                          children: [showAsMenu, scribbleAction, textAction])
                
        let barButtonRight = UIBarButtonItem(title: "Sort", image: UIImage(systemName: "ellipsis.circle.fill"), primaryAction: nil, menu: menu)
        navigationItem.rightBarButtonItems = [barButtonRight]
    }
}

This all works and produces the following when a user taps on the button in the navigation bar:

enter image description here

Tapping on the first menu item yields the desired effect:

enter image description here

But at times, I need to be able to also mark the first menu item (which is a submenu item) with a checkmark. I can't work out how to do this and have searched on Stackoverflow as well as the Apple Developer Forums etc and can't work it out. Any suggestions would be greatly appreciated.

Anthony
  • 720
  • 1
  • 6
  • 24

1 Answers1

0

if you only have to worry about iOS 15 and up, try passing in UIMenu.Options.singleSelection in to your UIMenu init that's driving the showAsMenu property.

var showAsMenu: UIMenu {
    return UIMenu(title: "Show As", 
                  image: UIImage(systemName: "questionmark.circle.fill"), 
                  identifier: .none,
                  options: .singleSelection,
                  children: showAsActions)
}

depending on how you want the primary menu to behave, you could instead pass that option into the menu init, as that option considers the menu it's passed into as well as all of it's submenus.

if you support iOS 14, unfortunately you'll probably have to resort to recreating the entire menu, updating the state of it's children as needed, and then setting the result back to UIBarButtonItem's menu property. see here: How to change the state for an UIAction inside UIMenu at runtime?

JERSH
  • 66
  • 5