FMMarkingMenu
is an implemtation of the marking menu UI pattern seen in applications such as Autodesk's Maya ported to iOS. Originally designed by Gordon Kurtenbach, marking menus allow users to navigate through and select from menu heirarchies using a single gesture which appears as a continous mark on the screen.
In my version, the user simply has to tap anywhere on the screen and the marking menu appears in the centre. Dotted menu item arcs indicate crossing that item will open a further menu and solid, thicker menu item arcs indicate an executable menu item.
Implementation is simple: create an instance of MarkingMenu
:
var markingMenu: FMMarkingMenu!
...and, typically in viewDidLoad()
, give it a target view controller, view and set of menu items:
markingMenu = FMMarkingMenu(viewController: self, view: view, markingMenuItems: markingMenuItems)
To respond to menu selections, FMMarkingMenu
requries a delegate that conforms to FMMarkingMenuDelegate
. This protocol contains one method:
func FMMarkingMenuItemSelected(markingMenu: FMMarkingMenu, markingMenuItem: FMMarkingMenuItem)
FMMarkingMenu
builds its menu from an array of FMMarkingMenuItem
instances and each FMMarkingMenuItem
can contain further FMMarkingMenuItem
instances to build a heirarchy. In this example, a menu contains two top level items: No Filter and Blur & Sharpen. The former has no sub items and will appear as a solid executable menu item, the latter has three sub items and will appear as a dotted menu item. When the user strokes across it they'll be presented with three further items, CIGaussianBlur, CISharpenLuminance and CIUnsharpMask:
let blur = FMMarkingMenuItem(label: "Blur & Sharpen", subItems:[FMMarkingMenuItem(label: "CIGaussianBlur"), FMMarkingMenuItem(label: "CISharpenLuminance"), FMMarkingMenuItem(label: "CIUnsharpMask")])
let noFilter = FMMarkingMenuItem(label: "No Filter")
let markingMenuItems = [noFilter, blur]
markingMenu = FMMarkingMenu(viewController: self, view: view, markingMenuItems: markingMenuItems)
FMMarkingMenu
can be installed in any project by simply copying three files:
Because FMMarkingMenu
uses a custom gesture recognizer, you'll also need to add the following to a bridging header:
#import <UIKit/UIGestureRecognizerSubclass.h>
The demo application allows the user to navigate through a selection of Core Image filters and apply to an image. The app is designed for iPad rather than being universal. I don't see FMMarkingMenu
as a user interface paradigm suited for iPhone (at this time!).
A Marking Menu Component for iOS in Swift
Extremely Efficient Menu Selection: Marking Menus for the Flash Platform
User Learning and Performance with Marking Menus
The Limits Of Expert Performance Using Hierarchic Marking Menus