Create a Cool 3D Sidebar Menu Animation
In this tutorial, you’ll learn how to manipulate CALayer properties on views in order to create a cool 3D sidebar animation. By Warren Burton.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Create a Cool 3D Sidebar Menu Animation
30 mins
- Getting Started
- Restructuring Your Storyboard
- Deleting the Old Structure
- Adding a New Root Container
- Adding Identifiers to View Controllers
- Creating Contained View Controllers
- Creating a Scroll View
- Creating Containers
- Adding Contained View Controllers
- Reconnect Menu and Detail Views
- Creating a Delegate Protocol
- Implementing the MenuDelegate Protocol
- Controlling the Scroll View
- Adding a Menu Button
- Creating a Hamburger View
- Installing the Hamburger View
- Adding Perspective to the Menu
- Manipulating the Menu Layer
- Rotating the Burger Button
- Where to Go From Here?
Many iOS apps need a menu to navigate between views or to let the user make choices. One commonly used design is a side menu.
You can easily make a side menu using a simple form, but how can you introduce a little delight into your UI? You want to put a smile on your users’ faces and bring them back to your app time and time again. One way to do this this is by creating a 3D sidebar animation.
In this tutorial, you’ll learn how to animate some UIView
elements by manipulating CALayer
properties to create a 3D sidebar animation. This animation was inspired by a To-Do app called Taasky.
Throughout this tutorial, you’ll work with the following elements:
- Storyboards
- Auto Layout constraints
- UIScrollView
- View controller containment
- Core Animation
If these elements sound unfamiliar, then you should start with some of our other iOS tutorials before returning to this one.
Getting Started
Before you begin, download the starter project, called TaskChooser, by using the Download Materials button at the top or bottom of this page.
Imagine you are creating a basic app for negotiating events with your colleagues or friends. Thumbs-up if you’re in, thumbs-down if you can’t make it. You can even decline due to inclement weather.
Take a moment to look at the project. You’ll see it’s a standard Xcode Master-Detail template app that displays a table of images.
-
MenuViewController: A
UITableViewController
that uses a custom table view cell,MenuItemCell
, to set the background color of each cell. It also has an image. -
MenuDataSource: An object that implements
UITableViewDataSource
to provide the table data fromMenuItems.json
. This data could come from a server in a production situation. - DetailViewController: Displays a large image using the same background color as a cell that you’ve selected.
Build and run the app. You should see the starter project load with 7 rows of color and icons:
Use the menu to display which option you’ve selected:
This is functional, but the look and feel is rather ordinary. You want your app to both amaze and delight!
In this tutorial, you’ll refactor the Master-Detail app into a horizontal scroll view. You’ll embed the master and detail views inside container views.
Next, you’ll add a button to show or hide the menu. You’ll then add a neat 3D folding effect on the menu.
As a final touch for this 3D animation sidebar, you’ll rotate the menu button in sync with showing or hiding the menu.
Your first task is to convert MenuViewController
and DetailViewController
to a slide-out sidebar, where a scroll view contains the menu and detail views side-by-side.
Restructuring Your Storyboard
Before you can rebuild your menu, you need to do a little demolition. Time to pull out the sledgehammer and the safety glasses. :]
Open Main.storyboard in the Views folder of the Project navigator. You can see UINavigationController
, MenuViewController
and DetailViewController
connected by segues:
Deleting the Old Structure
The Navigation Controller Scene does not spark joy. Select that scene and delete it. Next, select the segue between MenuViewController
and DetailViewController
and delete that, too.
With that done, brush the dust off and get to work. :]
Adding a New Root Container
Since UINavigationController
is gone, you no longer have a top-level container for the view controllers in the project. You’ll add one now.
Select the Views folder in the Project navigator. Add a new file to the project by pressing Command-N. Then:
- Select iOS ▸ Cocoa Touch Class. Click Next.
- Name the class RootViewController.
- Ensure that RootViewController is a subclass of UIViewController.
- Make sure “Also create XIB file” is not checked.
- The language should be Swift.
Open Main.storyboard again.
Open the Object Library with the key shortcut Command-Shift-L and drag an instance of UIViewController to the storyboard.
Select View Controller Scene from the Object hierarchy, then open the Identity inspector. Set the Class field to RootViewController.
Next, open the Attributes inspector and check the Is Initial View Controller box.
Adding Identifiers to View Controllers
Since MenuViewController
and DetailViewController
are no longer connected by segues, you need a way of accessing them from your code. So, your next step is to provide some identifiers to do this.
Select Menu View Controller Scene from the Object hierarchy. Open the Identity inspector and set Storyboard ID to MenuViewController.
This string can be any sensible value, but an easy-to-remember technique is to use the name of the class.
Next, select Detail View Controller Scene from the Object hierarchy and do the same thing. Set Storyboard ID to DetailViewController.
That’s all you need to do in Main.storyboard. The rest of this tutorial will be in code.
Creating Contained View Controllers
In this section, you’ll create a UIScrollView
and add two containers to that scroll view. The containers will hold MenuViewController
and DetailViewController
.
Creating a Scroll View
Your first step is to create a UIScrollView
.
Open RootViewController.swift in the Project navigator. Delete everything that Xcode supplied from the inside of RootViewController
.
Add this extension above RootViewController
:
extension UIView {
func embedInsideSafeArea(_ subview: UIView) {
addSubview(subview)
subview.translatesAutoresizingMaskIntoConstraints = false
subview.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor)
.isActive = true
subview.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor)
.isActive = true
subview.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor)
.isActive = true
subview.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor)
.isActive = true
}
}
This is a helper that you’ll use a few times in this tutorial. The code adds the passed-in view as a subview, then adds four constraints to glue the subview inside itself.
Next add this extension at the end of the file:
extension RootViewController: UIScrollViewDelegate {
}
You’ll want to watch UIScrollView
for changes. That action comes later in the tutorial, so this extension is empty for now.
Finally, insert the following code inside of RootViewController
:
// 1
lazy var scroller: UIScrollView = {
let scroller = UIScrollView(frame: .zero)
scroller.isPagingEnabled = true
scroller.delaysContentTouches = false
scroller.bounces = false
scroller.showsHorizontalScrollIndicator = false
scroller.delegate = self
return scroller
}()
// 2
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor(named: "rw-dark")
view.embedInsideSafeArea(scroller)
}
// 3
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
Here’s what you’re doing in this code:
- First, you create a
UIScrollView
. You want to enable paging so that the content moves in atomic units inside the scroll view. You’ve disableddelaysContentTouches
so that the inner controllers will react quickly to user touches.bounces
is set to false so you don’t get a stretchy feel from the scroller. You then setRootViewController
as the delegate of the scroll view. - In
viewDidLoad()
, you set the background color and embed the scroll view inside the root view using the helper you added before. - An override to
preferredStatusBarStyle
allows the status bar to appear light on the dark background.
Build and run your app to show that it launches properly after this refactor:
Since you haven’t added the buttons and content to the new RootViewController
, you should only see the dark background you have set. Don’t worry, you’ll add them back in the next section.