Matt Gemmell

MGTileMenu

8 min read

I’m pleased to announce the release of MGTileMenu, an open source iOS GUI component providing a pop-up tile-based contextual menu. It’s designed for iOS 5, and uses ARC. It supports Retina and non-Retina devices, and works with VoiceOver. MGTileMenu is designed for use on iPad, but it will also work on iPhone and iPod touch.

MGTileMenu is released under an attribution license for free, and can also be licensed without the attribution requirement for a modest fee. MGTileMenu has no external dependencies. Here’s how it looks, at full Retina resolution:

MGTileMenu, page 1

MGTileMenu

Tile menus show five icon-tiles per ‘page’, with a sixth page-switching tile (“…”) used to switch to successive pages of tiles. You can have any number of pages of tiles. Here’s a demo movie of it in action:

Demo video of MGTileMenu

(Watch it on YouTube)

The placement of the page-switching tile depends on whether MGTileMenu is configured to be right-handed (the default) or left-handed, and will leave a gap for your finger in each case.

You can extensively configure MGTileMenu’s behaviour and appearance. There’s a delegate protocol to supply tile icons, and to customise tile backgrounds (with images, gradients or flat colours).

Emoticons menu

Emoticons menu

MGTileMenu also posts various notifications which may be useful. Naturally, it uses Core Animation extensively for a pleasant interaction experience.

MGTileMenu is designed with convenience in mind. Its default appearance and behaviour have been configured to suit most situations, and it will try to behave intelligently to minimise the work you have to do when using it (for example, it will sanity-check and adjust the position you tell it to display at, to ensure it’s fully visible, and will move to remain visible when the device rotates).

The controller’s own properties and methods, and the delegate protocol, have similarly been designed for maximum convenience. You should find MGTileMenu very easy to integrate and use, with minimal additional effort.

MGTileMenu includes a demo application, showing how to create and configure an example menu. In the demo application, you trigger a tile menu by double-tapping anywhere, but you’re naturally free to trigger MGTileMenu however you wish in your own code.

License and donations

MGTileMenu is released under its own attribution license (which is included with the source code). I’ve created and released this component, like all my other code, for the benefit of the iOS and Mac development community that I’m proud to be a part of.

I hope you’ll choose to support future code releases (and this blog) by making a donation, or buying a non-attribution license for the code.

If you find the code useful, you have the option of making a donation to support my work, which would be very much appreciated. You can do so via the button below, or directly to my PayPal email address (matt.gemmell at Gmail). I’d very much appreciate it, and it will go fully back into supporting future articles and code releases.

If you don’t want to (or cannot) provide attribution in your app, you can purchase a non-attribution license via my online license store.

Thanks for your support!

Downloading the code

You can get MGTileMenu on github.

Support, bugs and feature requests

There is absolutely no support offered with this component. You’re on your own! If you want to submit a feature request, please do so via the issue tracker on github.

If you want to submit a bug report, please also do so via the issue tracker, including a diagnosis of the problem and a suggested fix (in code). If you’re using MGTileMenu, you’re a developer – so I expect you to do your homework and provide a fix along with each bug report. You can also submit pull requests or patches.

Please don’t submit bug reports without a diagnosis and a fix!

Designing MGTileMenu

MGTileMenu was created as a way to show options or tools contextually, wherever your hand might be on the iPad’s screen. It’s for use in an app that I’m working on, and I thought it was worth releasing as a useful component.

I’d already experimented with a contextual tool interface that associates tools separately to each finger, but I wanted something much more conventional, less intimidating, and physically easier to operate/

My initial sketch of the tile idea in my notebook is below.

Initial sketch

Initial sketch

As you can see, the final control follows the sketch very closely. With only that single sketch and a couple of notes, I started creating a mockup in Photoshop. This is the first version:

First mockup

First mockup

The tiles are exactly the same size as app icons on the iPad’s Home screen, which provides a sensible consistency and presumably capitalises on Apple’s own research and testing. Believe it or not, the identical size was actually a happy coincidence: the first rounded-rectangle I drew by eye in Photoshop turned out to match iPad app icons to the pixel.

Having made the mockup, I felt there was something visually missing; the tiles needed something to unify them. A bezel seemed like a reasonable choice, so I started experimenting with the concept.

Round bezel with struts

Round bezel with struts

The round bezel looked fragile to me, and didn’t really reflect the grid-based layout of the tiles (it made me want to pull the corner-tiles inwards, breaking the visual stability of the menu). The ‘spokes’ (radial lines) also looked too busy, and created a strange association between the tiles and the Close button. The lines had to go.

Encompassing bezel

Encompassing bezel

My next try was a round-cornered bezel that I was much happier with, fully encompassing all of the tiles. It wasn’t bad, but it looked heavy and a bit static and boring. I wanted the menu to appear more dynamic, to match the Core Animation features I planned to add.

Final design

Final design

Trimming down the size of the bezel provided me with the final look. It still unifies the tiles and provides a ground for the Close button, but the fact that the tiles overhang the bezel’s edges looks more interesting and funky, to my eye.

I implemented the control to match the final concept. Here’s a screenshot of an actual MGTileMenu in action, using its default tile-background appearance:

Tile menu default appearance

Tile menu default appearance

And here’s a tile menu with some more colourful backgrounds, and one fewer tile.

MGTileMenu, page 2

MGTileMenu, page 2

I’m really pleased with how the appearance turned out; I think it’s a nifty, flexible, inviting control. The next step was to think about the interaction and animation.

Interaction design

I was very keen on the idea of making at least a nod towards the user’s preferred handedness. I placed my hands on the iPad’s screen and saw that we naturally tend to angle our wrists inwards, thus causing our pointing finger to have a diagonal rather than vertical profile against the screen.

A one-tile gap thus didn’t seem like enough, since in most cases the user’s finger would still partially obscure either the lower-left (for left-handed people) or lower-right (right-handed) tile. I decided on a two-tile gap, to give more room.

Configurable Handedness

Configurable Handedness

The gap also has the pleasant effect of reducing the number of tiles visible, which I hope will nudge developers towards having fewer options available in their apps that use the control.

I chose not to automatically mirror the order of tiles when left-handed mode is enabled, because I’m not convinced there’s an absolute correlation between reading/comprehension order and handedness. The delegate object for the control can still readily flip the order of tiles depending on the user’s handedness if so desired.

So much for how the tile menu looks. The appearance and intended use of the control immediately implied several places where I’d want to incorporate some animation:

  1. When the menu appears or disappears.
  2. When the user switches between pages of tiles.

Appearance and disappearance of the menu itself were simple and obvious enough: a zoom-up and fade-in to appear, and a zoom-down and fade-out to disappear. The interesting question was how to transition from one page to another, given that it would involve changing all of the tiles simultaneously.

Given that the tiles overhang the bezel, creating a dynamic tension around the control, I decided to make the tiles congregate in the centre of the bezel when the user switches pages. The tiles would fly into the middle, change into suitable tiles for the next page, and then return to their positions.

A naïve implementation of the animation would move all the tiles in sync, which gives an unpleasantly robotic effect. I’ve slowed the animation down so you can see it in this short video.

Uniform tile movement

(Watch it on YouTube)

By adding an offset to the beginning of each tile’s animation, we get a much more pleasant flocking sort of effect, shown here slowed down once again:

Staggered tile movement

(Watch it on YouTube)

The tile-switching animation is a simple cross-fade, to avoid a jarring sudden change into a different tile.

The videos above show the final animation order, but initially the tiles moved in their programmatic, logical order of left-to-right, top-to-bottom.

Tile index order

Tile index order

That gave a haphazard, disordered impression (particularly the wrap from the end of the top row to the beginning of the second row). I felt it would be more logical if the animation proceeded from the page-switching tile, since that’s what the user taps to initiate the transformation in the first place. Thus, the final animation runs clockwise, starting with the middle-left tile (just above the switching tile). The animation order is horizontally flipped if the menu is in left-handed mode.

Tile animation order

Tile animation order

It took a little more work for me to implement, but it’s a much nicer experience for the user.

The delegate API (and MGTileMenu’s own code generally) still indexes the tiles on a left-to-right, top-to-bottom basis internally, because I felt that it’ll require less mental acrobatics for the developers who make use of the control.

Final thoughts

I’ve enjoyed creating MGTileMenu, and I really hope you’ll find it useful – a lot of love has gone into the design and the code. Please do consider supporting this blog and my future code releases with a donation or a non-attribution license.

I’ve also written an article about the other side of MGTileMenu’s development: the API, and why I designed it the way I did. After all, APIs are UX for developers. The article uses MGTileMenu as an example, but applies generally to all iOS (and OS X) component development.

To keep up to date, you should follow me (@mattgemmell) on Twitter. Enjoy MGTileMenu!