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.