Adding Menus and Keyboard Shortcuts


As I continue to work on Wasted Time, I now have added working keyboard shortcuts, and menu items to both the iPad and macOS versions. I can’t wait for Big Sur and iPadOS 14 to come up so I can release these to the world.

First a few screenshots

The code ended up not being to difficult, once I figured it out. Of course, that is almost always the case. Moving from all the programming habits I developed in college and the few years that I made my living as developer, to modern languages and architectures, has been hard. While I fully understand the concepts, putting it in practice can be difficult. So let’s look at the code behind the Menu Builder function in Swift:

    override func buildMenu(with builder: UIMenuBuilder) {
        super.buildMenu(with: builder)
        
        // Ensure that the builder is modifying the menu bar system.
        guard builder.system == UIMenuSystem.main else { return }
        
        // Meeting Menu
        let advanceMeetingStatus = UIKeyCommand(title: "Advance Meeting Status", action: #selector(handleKeyAdvanceMeetingStatus(sender:)), input: UIKeyCommand.inputRightArrow, modifierFlags: .alternate, propertyList: UIKeyCommand.inputRightArrow)
        let incrementParticipants = UIKeyCommand(title: "Increment Participants", action: #selector(handleKeyIncrementParticipants(sender:)), input: UIKeyCommand.inputUpArrow, modifierFlags: .alternate, propertyList: UIKeyCommand.inputUpArrow)
        let decrementParticipants = UIKeyCommand(title: "Decrement Participants", action: #selector(handleKeyDecrementParticipants(sender:)), input: UIKeyCommand.inputDownArrow, modifierFlags: .alternate, propertyList: UIKeyCommand.inputDownArrow)
        let cancelMeeting = UIKeyCommand(title: "End Meeting Immediately", action: #selector(handleKeyCancelMeeting(sender:)), input: UIKeyCommand.inputLeftArrow, modifierFlags: .alternate, propertyList: UIKeyCommand.inputLeftArrow)
       
        let advanceMeetingItem = UIMenu(title: "Advance Meeting", image: nil, identifier: UIMenu.Identifier("advanceMeetingStatus"), options: .displayInline, children: [advanceMeetingStatus])
        let incrementParticipantsItem = UIMenu(title: "Add Participants", image: nil, identifier: UIMenu.Identifier("incrementParticipants"), options: .displayInline, children: [incrementParticipants])
        let decrementParticipantsItem = UIMenu(title: "Remove Participants", image: nil, identifier: UIMenu.Identifier("decrementParticipants"), options: .displayInline, children: [decrementParticipants])
        let cancelMeetingItem = UIMenu(title: "Cancel Meeting", image: nil, identifier: UIMenu.Identifier("cancelMeeting"), options: .displayInline, children: [cancelMeeting])
        
        
        let meetingMenu = UIMenu(title: "Meeting", children: [advanceMeetingItem,incrementParticipantsItem,decrementParticipantsItem,cancelMeetingItem])
       
        // View Menu
        let meetingView = UIKeyCommand(title: "Meeting View", action: #selector(handleKeyCommand1(sender:)), input: "1", modifierFlags: .command, propertyList: 1)
        let setupView = UIKeyCommand(title: "Setup View", action: #selector(handleKeyCommand2(sender:)), input: "2", modifierFlags: .command, propertyList: 2)
        let totalsView = UIKeyCommand(title: "Totals View", action: #selector(handleKeyCommand3(sender:)), input: "3", modifierFlags: .command, propertyList: 3)
        let helpView = UIKeyCommand(title: "Help View", action: #selector(handleKeyCommand4(sender:)), input: "4", modifierFlags: .command, propertyList: 4)
        
        let meetingViewItem = UIMenu(title: "Meeting View", image: nil, identifier: UIMenu.Identifier("meetingView"), options: .displayInline, children: [meetingView])
        let setupViewItem = UIMenu(title: "Setup View", image: nil, identifier: UIMenu.Identifier("setupView"), options: .displayInline, children: [setupView])
        let totalsViewItem = UIMenu(title: "Totals View", image: nil, identifier: UIMenu.Identifier("totalsView"), options: .displayInline, children: [totalsView])
        let helpViewItem = UIMenu(title: "Help View", image: nil, identifier: UIMenu.Identifier("helpView"), options: .displayInline, children: [helpView])
        
        let tabsMenu = UIMenu(title: "Tabs", children: [meetingViewItem, setupViewItem, totalsViewItem, helpViewItem])
        
        builder.insertSibling(meetingMenu, afterMenu: .edit)
        builder.insertSibling(tabsMenu, afterMenu: .edit)
        builder.remove(menu: .file)
        builder.remove(menu: .edit)
        builder.remove(menu: .format)
        builder.remove(menu: .help)
        
    }

The net of this code is to build up the actions, then the items, and then attach the items to a new UIMenu object. I add the various items ad children to the UIMenu, and then insert the UIMenu after the file menu. Since I don’t use the file menu, I then remove it, along with edit, format and help.

Not too hard.