in iOS, tutorial

Tutorial: create a menu using UIKit Dynamics

Before releasing the new version of WakeUp app, I posted a video about a new menu I was working on using mainly UIKit Dynamics.

I did promise a tutorial about it, and here it comes! This is an example of what we will do.

dynamicsMenu

I have decided to modify slightly the way I write tutorials. I will write and explain the most important parts of the code, but I won’t go through every single line of code. I have uploaded a project in Github, where I have tried to comment the code as good as possible, use it as an extension of this tutorial.

This post is not about explaining UIKit Dynamics, I will assume you understand the basic concepts behind the framework.
For reference, I strongly recommend to watch the video talking about it from Standford University.

Find here also 2 nice introduction posts about UIKit Dynamics.
Introduction to UIKitDynamics
Adding Animated Effects to iOS App Using UIKit Dynamics

For a better understanding of this particular example and before we start writing code, let me explain how everything works.

– There are 2 basic parts: Main menu and submenus. There is only 1 Main menu (with 3 items int his particular example). Each item (UIButton) will show a submenu when pressed. Each submenu has X items (they can be defined).
– There are 2 UIDynamicAnimators. The first one takes care of the Main Menu items. The second one, takes care of the presented submenu (we won’t have 2 submenus presented at the same time).
– We will use 3 different behaviours: gravity, collision, push and snap.

To start creating the menu, I have set up the Main Menu (3 buttons) using storyboard for a quickly setup. It is a very basic setup, just add the buttons in any position you like, change the tag to each button (I will use button’s tag to know which button has been pressed) and customise them.
Connect the buttons to its class using an outlet collection and link them to an IBAction.

Before we talk about the IBAction triggered by the main buttons, lets quickly set up the rest of the menu on the viewDidLoad.

The above code is pretty straight forward. First we do any additional setup to the main buttons (round the edges). Next, we create the submenus. You may argue that locating the buttons outside the screen is not a very neat solution. Yes, we could create the submenu arrays on the flight right when the user wants to access to them, but for a quick tutorial will keep it like this.

This is the action triggered by any of the 3 main menu buttons.

The only thing I need to point here is that the 3rd button won’t present any submenu. I left it there as an example if another action would be needed (like present another VC).

Let’s start with the fun!

As you can see and as you will see, I like to clean up first any previous behaviours. You could modify existing behaviours (i.e. change gravity direction or magnitude), but I thought it will be easier and cleaner if we start from scratch every time we call the method.

First thing we need to do is send the 3 buttons to the left. To do that we add a gravity behaviour pointing to the left. Also we add some vertical stoppers for the buttons. The first one is outside the screen and will take care of the non-pressed buttons, and the second one will be the edge of the screen and will stop the pressed button.
To make the effect a bit more interesting, we will also add a Push behaviour to the pressed button against the gravity.

Apart from sending the main buttons to the left, we also want the corresponding submenu to appear.
What we do here is locate the buttons far away to the right, with a bit of offset from one to the next so the effect is a bit nicer.
After that, we apply the same gravity as before and create a new vertical stopper, so the buttons can collide to it and stop in the middle of the screen.

Last thing we need to do is allow the user to come back to the main menu.
First thing we do is dismiss the submenu buttons with a kind of ‘explosion + fall’ effect. To do that, we add a random push behaviour (I have tried to set an angle close to -M_PI, pointing up) along with normal gravity (when I say normal I mean pointing down).
Finally, to bring back the main menu buttons, we snap them to a fixed point. As you can notice, I have had to ‘tweak’ the behaviour using UIDynamicItemBehavior. This allow us to modify some physical properties like the density, elasticity, etc.

I hope you have enjoyed the tutorial. Find the project on github

Leave a Reply

  1. Hey Victor,
    first of all thanks for the great tutorial. But I have one question about the buttons you made. They have a number and a circle around it. I saw that you rounded the corners, but that alone doesn’t draw a circle.
    I tried it with button.layer.borderWidth and borderColor but when I click the button, only the number gets greyed out, not the circle.
    Can you tell me how you did that?

    Cheers

    • Hello Codey,
      Thank you for your comment.
      I used a PNGs for each number setting them as button image (the PNG contain the number and the circle), this is why it gets greyed out.
      The way you did it is better than mine, however you will need to implement highlighted and selected states yourself to achieve the greyed out effect.
      I hope this helps!

      • Hey Victor,
        thanks for your reply.
        I added this code:

        button.addTarget(self, action: “highlightButton:”, forControlEvents: UIControlEvents.TouchDown)

        button.addTarget(self, action: “unhighlightButton:”, forControlEvents: UIControlEvents.TouchUpInside)

        button.addTarget(self, action: “unhighlightButton:”, forControlEvents: UIControlEvents.TouchDragOutside)

        In the methods I changed the borderColor. Now everything works fine!

Webmentions

  • nouveau maillot psg 2014 December 23, 2014

    That’s great! I am glad you could make it :D