Over a million developers have joined DZone.

Hybrid Marking Menu/Radial Slider Swift Component for iOS

Learn to create a marking menu component for iOS that allows the user to add blur and sharpen filters, and adjust brightness, saturation, and contrast.

· Mobile Zone


Over the last few weeks, I've been evolving my original marking menu component for iOS and made some pretty significant changes:

  • Distributing the menu items over a full circle meant that often some items were hidden by my finger. Although positioning the menu in the centre of the screen mitigated this somewhat, I've now changed the layout to a semi-circle from 9 o'clock through 3 o'clock.
  • The marking menu now pops up at the touch position.
  • Marking menu items can now be radial sliders to set a normalised value. The radial sliders position themselves underneath the touch location. By moving the touch away from the origin and, therefore, increasing the radius of the radial dial, the user can increase the size of the radial dial to make very precise changes.
  • Marking menu items can be set to selected and be given categories

To demonstrate these changes, I've updated the demonstration application. The application allows the user to add different blur and sharpen filters and update the blur and sharpen amounts along with the brightness, saturation and contrast. 

The top level menu contains three items: BlurSharpen and Color Adjust.

Blur contains three items to select the blur type and a slide. Its definition in Swift looks like this:

    let blurAmountSlider = FMMarkingMenuItem(label: "Blur Amount", valueSliderValue: 0)

    let blurTopLevel = FMMarkingMenuItem(label: FilterCategories.Blur.rawValue, subItems:[
        FMMarkingMenuItem(label: FilterNames.CIGaussianBlur.rawValue, category: FilterCategories.Blur.rawValue, isSelected: true),
        FMMarkingMenuItem(label: FilterNames.CIBoxBlur.rawValue, category: FilterCategories.Blur.rawValue),
        FMMarkingMenuItem(label: FilterNames.CIDiscBlur.rawValue, category: FilterCategories.Blur.rawValue),
        blurAmountSlider])

You can see here that the slider uses the valueSliderValue constructor which sets its isValueSlider property to true. When the user marks over that menu item, the radial slider pops up.

You may also notice that the other three items have a category set. Although the marking menu component does't really care about categories, the host application may do. In my demo application, I only want the user to be able to select one type of blur; either GaussianBox or Disc. 

To do this, all three items share the same Blur category and in my FMMarkingMenuItemSelected delegate method, I invoke setExclusivelySelected to force only one selected menu item per category:

    FMMarkingMenu.setExclusivelySelected(markingMenuItem, markingMenuItems: markingMenuItems)

Selected menu items are coloured red and have their isSelected property set to true.

The changes the layout are set by some Boolean properties. If and when I post this component to OS X (where using a mouse means my chubby fingers won't hide the menu), the layout can be returned to a full circle by setting layoutMode to FMMarkingMenuLayoutMode.Circular.

This version of FMMarkingMenu is written in Swift 2.0 under Xcode 7 and I've only been able to test it on an iPad running iOS 9. The code makes liberal use of the new guard syntax which I absolutely love (see this great article from Natasha The Robot to learn more about guard). Being able to optionally bind a load of constants and easily exit a method early if one of them fails makes coding a breeze:

    guard let category = FilterCategories(rawValue: markingMenuItem.category!),
        filterName = FilterNames(rawValue: markingMenuItem.label)?.rawValue else
    {
        return
    }

I hope this post offers a good insight into the component. Please reach out to me via Twitter (@FlexMonkey) if you have a questions or comments. The source code for the project lives in my GitHub repository here

Finally, a note on patent issues. I've reached out to Autodesk to ask about patent infringement issues without success. I'm confident that my component is sufficiently different from theirs (especially with all these recent changes) that there is no infringement. Furthermore, there's plenty of "prior art" (for example Don Hopkins has been playing with radial menusin the Sims for years) and other applications (e.g. Modo and Blender) use similar interaction paradigms.

Topics:
marking menu ,mobile ,swift

Published at DZone with permission of Simon Gladman, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}