Yalantis: iOS, Android And Web App Development Company

How We Created Guillotine Menu Animation for iOS

Have you ever wondered why a sidebar in apps has to be a “side” bar? Why not to make it a “topbar,” or a “bottombar,” or a “cornerbar,” etc.?

A new animated trend in the generation of navigation bars is what we are going to talk about this time. Animations are fun but most importantly, they are useful. They can change your way of thinking, make your product catchy, and improve user experience. Here is how our designer Vitaly Rubtsov came up with this great idea:

“From time to time every designer gets bored. All these fixes, cuts, specifications – they leave very little space for imagination. In these minutes I feel like opening my Adobe After Effects and creating something interesting.

When I started thinking about what to create this time, I caught myself on a thought that a typical sidebar menu which sadly gets out of the left part of the screen moving all content to the right, is so unbearably boring! What if a sidebar becomes a topbar? It’s going to drop down from the top of the page and turn in a unique way. Sounds like fun, doesn’t it?”

Vitaly’s topbar animation was implemented in Swift by our iOS developer Maksym Lazebnyi, who gave it a funny name Guillotine Menu – the way it drops down from the top reminds a bit of a notorious killing machine. After all, our animation is a killer feature as well!

Check it out on Dribbble and GitHub.

Guillotine menu animation by Yalantis

How we developed the Guillotine Menu

by Maksym Lazebnyi

In fact, our iOS team saw lots of ways to implement the animation. We chose the one that allows a developer to customize a menu in every possible way right from the Storyboard.

To create our transitioning animation we built a subclass of the UIStoryboardSegue and a custom animation controller. Basically, this is all you need for this sort of a menu animation, unless you want to make it look really awesome. We surely did! That’s why we created a couple of additional classes.

Overall, you need three classes and one UIView extension to make the animation. Here are these guys:

  1. GuillotineMenuSegue. It’s a UIStoryboardSegue which is a subclass of UIStoryboardSegue. We used it for a modal presentation of the menu and also for presenting the animation controlled by GuillotineMenuTransitionAnimation class. GuillotineMenuSegue allows us to add some transparency to the menu as well (not this time though).
  2. GuillotineMenuTransitionAnimation. This class presents a view of the GuillotineMenuViewController of our custom animation.
  3. GuillotineMenuViewController. It’s a UIViewController subclass for the menu.

We also used UIViewExtension to set four constraints for a subview so that it could fit a superview.

Now let’s look at each class separately.

Guillotine Menu Segue

There is nothing special in this class, so we’ll only mention a couple of things.

In the overriden init method we check if a destination view controller conforms a protocol for GuillotineAnimationProtocol (we’ll speak about this protocol a bit later). In the overriden perform method we set self as a transitioning delegate.

In the delegate method animationControllerForPresentedController we set the retain association between self and the GuillotineMenuViewController to keep it alive while it’s on screen.

GuillotineMenuTransitionAnimation

Here’s where all the magic happens!

At first we considered UIView.animateWithDuration usingSpringWithDamping & initialSpringVelocity. But after a closer look at the animation we changed our mind. The view of the menu needs to produce a colliding effect with a rebound when it’s striking the left border of the superview, which it wouldn’t do should we use the method animateWithDuration (it would spring through the border of the superview, instead).

That’s why we chose UIDynamicAnimator.

In order to create the animation, GuillotineMenuTransitionAnimation class must conform UIViewControllerAnimatedTransitioning protocol. As you know, it has 2 methods:

  1. func. transitionDuration. Duration of the animation does not matter much in our case, so we can return any time interval.
  2. func animateTransition is called when the menu has to open or close.

How we calculated the location of the animation

We should also know a precise location of the animation. GuillotineMenuTransitionAnimation requires GuillotineMenuViewController to provide the coordinates of the center of the menu button since it’ll be the anchor point for a turn. Actually there are some more properties we need from the GuillotineMenuViewController, so we decided to create a protocol that the GuillotineMenuViewController is supposed to conform:

@objc protocol GuillotineAnimationProtocol: NSObjectProtocol {
 func navigationBarHeight() -> CGFloat
 func anchorPoint() -> CGPoint
 func hostTitle () -> NSString
}

Here:

  1. navigationBarHeight() -- GuillotineMenuViewController starts to show the animation when it’s turned by 90° while covering a navigation bar. We need to set the position of the view of the GuillotineMenuViewController to CCPoint(0, navigationBarHeight)
  2. anchorPoint() is a turning center for our animation and therefore, a center of the menu button of the GuillotineMenuViewController.
  3. func hostTitle() is used to ask the GuillotineMenuViewController for the title of the host View Controller.

How we implemented the drop down and turn

To implement the drop down and turning of the animation, we used UIDynamicAnimator with four behaviours:

  1. UIPushBehavior is a force that pulls the view towards the bottom or the top of the screen depending on whether we show or dismiss the animation.
  2. UIAttachmentBehavior is like a "nail" which holds the view in the center of the menu button.
  3. UICollisionBehavior. We created a boundary which covers the area from the middle of the height of the superview to its bottom left corner. It’s needed for the GuillotineMenuViewController to collide with the superview at the end of the turning path.
  4. UIDynamicItemBehavior is needed to make the view rebound after the collision.

Basically, the animation starts with the GuillotineMenuViewController’s view turning by 90° with the help of CGAffineTransformRotate. We set its frame position to CCPoint(0, navigationBarHeight). Then, we add the view to the array of items for each UIDynamicBehavior.

UIDynamicAnimator continues animating the menu until all forces created by the behaviors get balanced.

By using UIDynamicAnimatorDelegate protocol we can inform the view controller about the completion of the animation. To do this, we call a method endAppearanceTransition().

The tricky part here was setting up the anchorPoint. For a correct animation it requires to be positioned at an equal distance from the left side of the GuillotineMenuViewController's view and the bottom of the navigation bar. Also, it should properly change its position if a device is rotated. But the problem is that GuillotineMenuTransitionAnimation class calls the method anchorPoint() delegate before a method viewDidLayoutSubviews() is called.

We had to hardcode the position of buttons at the landscape device orientation.

UIViewExtension

It’s a simple extension which adds constraints for the subview to fit the superview boundaries. UIViewExtension is pretty much self explanatory.

Guillotine Menu View Controller

This view controller can be subclassed or rewritten from scratch for any kind of customization. The main thing is that it should conform the GuillotineAnimationProtocol.

How can you customize the animation?

Feel free to customize the view of the menu in every possible way! Just create a custom GuillotineMenuSegue from your host view controller to your menu view controller that conforms ActivityAnimationProtocol in the interface builder and you are ready to go.

To be honest, I started creating this animation thinking it’s quite simple and there is a little to no challenge in it. But now we must admit that there is a huge potential for iOS developers. We found out that our animation could also be implemented as a simple animated view or a subclass of UINavigationController with a custom navigation bar. We intend to update the component by creating a complete subclass of UINavigationViewController with custom transfer animations.

So keep yourself posted!

You can find the sample of the project and its design here:

P.S. Follow us on Twitter and Facebook until we are working on including an RSS feed and blog subscription.

Design

How We Built Pull To Make Soup Animation

Design

UIDynamics, UIKit or OpenGL? 3 Types of iOS Animations for the Star Wars

Design

How We Created Tab Bar Animation for iOS

Excited to create something outstanding?

We share the same interests.

Let's team up!