Sie sind auf Seite 1von 20

How To Add a Slide-out Sidebar Menu in Your Apps

Editors note #1: This post has been updated for Xcode 6 and iOS 8. The demo app now
supports the latest version of SWRevealViewController.
Editors note #2: If youre using Swift, please check out the Swift version of the tutorial
here.
How can I create a slide-out sidebar menu in my app? This is one of the most frequently
asked questions we got from our readers. So this week well show you how create a slideout navigation menu similar to the one you find in the Facebook app.
For those who are unfamiliar with slide out navigation menu, Ken Yarmost gave a good
explanation and defined it as follows:
Slide-out navigation consists of a panel that slides out from underneath the left or
the right of the main content area, revealing a vertically independent scroll view that
serves as the primary navigation for the application.
Since Facebook app introduced this slide-out sidebar design, it quickly becomes a
standard way to implement navigation menu. You can easily find this design pattern in
most of the popular content-related apps such as Path, Mailbox, Gmail, etc.

The slide-out design pattern lets you build a navigation menu in your apps but without
wasting the screen real estate. Normally, the navigation menu is hidden behind the front
view. The menu can then be triggered by tapping a list button in the navigation bar. Once
the menu is expanded and becomes visible, users can close it by using the list button or
simply swiping left on the content area.
With so many free pre-built solution on GitHub, were not going to build the slide-out
navigation menu from scratch. Instead, well make use of a library called
SWRevealViewController. Developed by John Lluch, this excellent library provides a quick
and easy way to put up a slide-out navigation menu and its available for free.
Read on and develop a demo app together.

A Glance at the Demo App


As usual, well build a demo app to show you how to apply the SWRevealViewController.
The app is very simple but not fully functional. The primary purpose of the app is to walk
you through the implementation of slide-out navigation menu. The navigation menu will
work like this:

User triggers the menu by tapping the list button at the top-left of navigation bar.
User can also bring up the menu by swiping right on the main content area.
Once the menu appears, user can close it by tapping the list button again.
User can also close the menu by dragging left on the content area.

Creating the Xcode Project


With a basic idea about what well build, lets move on. You can create the Xcode project

from scratch and design the user interface similar to below:

However, to save your time from setting up the project, you can download the Xcode
project template to start with.

The project already comes with:


A pre-built storyboard with all the view controllers needed
A pre-built view controller classes including MapViewController and
PhotoViewController
The MapViewController is implemented to display a map
The PhotoViewController is implemented to display a photo in an image view
All icons and images needed for the app (credit: thanks for the free icon from
Pixeden)

Importing the SWRevealViewController Library


As mentioned, well use the free SWRevealViewController library to implement the slideout menu. So, first download the library from GitHub and extract the zipped file.
After you extract the file, you should find SWRevealViewController.h and
SWRevealViewController.m. In the project navigator, right-click SidebarDemo folder and
select New Group. Name the group SWRevealViewController. Import both files into the
Xcode project and put them under SWRevealViewController.

Associate the Front View and Rear View Controller


One of the beauties of the SWRevealViewController library is that it provides the built-in

support of Storyboard. When implementing sidebar menu using SWRevealViewController,


developers have to associate the SWRevealViewController with a front and a rear view
controller using segues. The front view controller is the main controller for displaying
content. In our storyboard, its the navigation controller which associates with another
view controller for presenting news content. Apparently, the rear view controller is the
controller for showing the navigation menu. Typically the menu is implemented by using
UITableViewController.

In the Xcode project template, weve pre-built the front and rear view controllers for you.
What you have to do is to define segues between the SWRevealViewController and
front/rear view controller.

First, select the initial view controller and change its class to SWRevealViewController.

Next, press and hold the control key. Click the SWRevealViewController and drag it to the
Menu view controller. After releasing the button, youll see a context menu for segue
selection. In this case, select reveal view controller set segue. This defines a custom
segue SWRevealViewControllerSetSegue. This custom segue tells
SWRevealViewController that the view controller connected is the initial view controller.
Note: If youre using an older version of SWRevealViewController, please note that the
SWRevealViewControllerSegue is now deprecated. You should use
SWRevealViewControllerSetSegue instead.
Repeat the same procedures to connect SWRevealViewController with the navigation
controller of the main view controller (containing News Frontpage).

Select the segue between SWRevealViewController and the navigation controller. In the
attributes inspector, set the segue identifier to sw_front. This is the default identifier that
indicates a transition of front view controller.
For the segue between SWRevealViewController and the sidebar view controller, set the
segue identifier to sw_rear. This identifier tells SWRevealViewController that the
controller represents the rear view (i.e. the sidebar menu).

If you compile and run the app, youll see an app displaying the News Frontpage. But
thats it. You wont see the sidebar menu when tapping the list button. We havent
implemented the action method yet.
Open MainViewController.m, which is the controller class of News Frontpage. Add the
following import statement:
#import
"SWRevealViewController.
h"

#import "SWRevealViewController.h"

Next, add the following code in the viewDidLoad: method:


SWRevealViewController
*revealViewController =
self.revealViewController;
if ( revealViewController
SWRevealViewController *revealViewController = self.revealViewController;
)
{
if ( revealViewController )
[self.sidebarButton
setTarget:
self.revealViewController];
{
[self.sidebarButton
setAction:[self.sidebarButton
@selector(
setTarget: self.revealViewController];
revealToggle: )];
[self.view
[self.sidebarButton setAction: @selector( revealToggle: )];
addGestureRecognizer:sel
f.revealViewController.pan

[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
}

The SWRevealViewController provides the revealToggle: method to handle the expansion


and contraction of the sidebar menu. As you know, Cocoa uses the target-action
mechanism for communication between a control and another object. We set the target of
the sidebar button to the reveal view controller and action to the revealToggle: method.
So when the sidebar button is tapped, itll call the revealToggle: method to display the
sidebar menu. Lastly, we also add a gesture recognizer. Not only you can use the list
button to bring out the sidebar menu, user can swipe the content area to activate the
sidebar.
Try to compile and run the app in the iPhone simulator. Tap the list button and the sidebar
menu should appear. Tap the button again to close it. You can also swipe right on the
content area to open the menu just like the figure below.

Before moving on, add the same code snippet in the viewDidLoad: method of both
PhotoViewController.m and MapViewController.m. The app should show up the sidebar
when a user taps the list button in these two view controllers.

Adding the Menu Items in Navigation Menu


With just a few lines of code, you already implement the slide-out navigation menu. Cool,
right?
However, the menu is now empty. Well now add a few items and show you the transition
from one item to another. The sidebar view controller is just a simple table view controller.
For sake of simplicity, well design the sidebar menu right in the storyboard.
The first table cell of the Sidebar View Controller is defined with the title APPCODA. If
you dont like it, just change it to whatever you prefer. The only thing you have to ensure is

to keep the cell identifier as title, which well refer it later in our code.
Okay, lets add a few more menu items. To begin, select the prototype cell and change the
number of prototype cells to 8 in the attributes inspector. You should end up with a
screenshot similar to below:

Change the APPCODA label of the second cell to News. Optionally, you can change
the color of label to dark gray and set the font to Avenir Next in the attributes inspector.
Next, drag a image view object from the object library to the cell. Set the size of image
view to 3838 and change the image to news.png.
Next, select the cell and set the cell identifier as news in the attributes inspector. You
should end up with a cell similar to the screenshot below.

Repeat the above procedures to add the following menu items:


Comments (set the images as comments.png and cell identifier as comments)
Map (set the images as map.png and cell identifier as map)
Calendar (set the images as calendar.png and cell identifier as calendar)
Wishlist (set the images as wishlist.png and cell identifier as wishlist)
Bookmark (set the images as bookmark.png and cell identifier as bookmark)
Tag (set the images as tag.png and cell identifier as tag)
If youve done everything correct, your sidebar view controller should look like this:

After completing the user interface, lets implement the code for displaying the table cell.
Select the SidebarViewController.m and add the following import statement:
#import
"SWRevealViewController.
h"

#import "SWRevealViewController.h"

Next, declare the menuItems variable to store the cell identifier of the menu items:
@implementation
SidebarViewController {
NSArray *menuItems;
}

@implementation SidebarViewController {
NSArray *menuItems;
}

Update the viewDidLoad: method to the following:


- (void)viewDidLoad
{
[super viewDidLoad];
menuItems
=
- (void)viewDidLoad
@[@"title", @"news",
@"comments", @"map",

{
[super viewDidLoad];
menuItems = @[@"title", @"news", @"comments", @"map", @"calendar", @"wishlist",
@"bookmark", @"tag"];
}

The above code is very straightforward. We simply initialize the menu item array with the
values of cell identifier. Then edit the numberOfSectionsInTableView: method to return 1
and the numberOfRowsInSection: method to return the correct number of table row:
(NSInteger)numberOfSecti
onsInTableView:
(UITableView *)tableView {
//-Return
the number of
(NSInteger)numberOfSectionsInTableView:(UITableView
sections.
return 1;
// Return the number of sections.
}
- (NSInteger)tableView:
return 1;
(UITableView *)tableView
numberOfRowsInSection:
}
(NSInteger)section {
// Return the number of
- in
(NSInteger)tableView:(UITableView
*)tableView
rows
the section.
return
menuItems.count;
// Return the number of rows in the section.
}

*)tableView {

numberOfRowsInSection:(NSInteger)section {

return menuItems.count;
}

Lastly, change the cellForRowAtIndexPath: method to the following:


- (UITableViewCell
*)tableView:(UITableView
*)tableView
cellForRowAtIndexPath:
(NSIndexPath
*)indexPath *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
- (UITableViewCell
{
*)indexPath {
NSString *CellIdentifier
= [menuItems
NSString *CellIdentifier = [menuItems objectAtIndex:indexPath.row];
objectAtIndex:indexPath.r
ow];
UITableViewCell
*cell = *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
UITableViewCell
[tableView
forIndexPath:indexPath];
dequeueReusableCellWith
Identifier:CellIdentifier
forIndexPath:indexPath];
return cell;

return cell;

The code simply gets the cell identifier of the specified table cell from the menuItems
array for display. Now compile and run the app again. Tap the list button and youll find a
slide-out navigation menu with menu items.

Implementing Menu Item Selection


Youve already built a visually appealing sidebar menu. There is still one thing left. For
now, we havent defined any segues for the menu item. When you select any of the menu
items, it will not transit to the corresponding view.
To keep the demo app simple, well only connect the menu item with three view
controllers. I think this should give a pretty good demonstration to show you how it works.
Here are what were going to do:
Connect the News cell item with the main view controller using a reveal view

controller push controller segue


Connect the Map cell with the map view controller using a reveal view controller
push controller segue
For the rest of the menu items, they will be associated with the photo view controller
using the same type of segue. But well display different photos for different menu
items.
Okay, go back to storyboard. First, select the map cell. Press and hold the control key and
click on the map cell. Drag to the navigation controller of the map view controller and
select the reveal view controller push controller segue under Selection Segue.

Repeat the above procedure for the News cell item, but connect it with the navigation
controller of the main view controller.
For the rest of menu items including comments, calendar, wishlist, bookmark and tag,
connect them one by one with the navigation controller of the photo view controller and
set the segue identifier as showPhoto. Well use this identifier to differentiate the segue
from the previous two we created.

Once you complete the configuration of segues in storyboard, open the


SidebarViewController.m. First add the following import statement:
#import
"PhotoViewController.h"

#import "PhotoViewController.h"

Then insert the prepareForSegue: method to manage the transition.


- (void)prepareForSegue:
(UIStoryboardSegue
*)segue sender:(id)sender
{

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

// Set the title of


navigation bar by using
the menu items
NSIndexPath
*indexPath
// Set
= the title of navigation bar by using the menu items
[self.tableView
indexPathForSelectedRow
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
];
UINavigationController
UINavigationController
*destViewController =
*destViewController
=
(UINavigationController*)s
(UINavigationController*)segue.destinationViewController;
egue.destinationViewCont
roller;
destViewController.title = [[menuItems objectAtIndex:indexPath.row] capitalizedString];
destViewController.title
= [[menuItems
objectAtIndex:indexPath.r
ow] capitalizedString];

// Set the photo if it navigates to the PhotoView


if ([segue.identifier isEqualToString:@"showPhoto"]) {
UINavigationController *navController = segue.destinationViewController;
PhotoViewController *photoController = [navController childViewControllers].firstObject;
NSString *photoFilename = [NSString stringWithFormat:@"%@_photo", [menuItems
objectAtIndex:indexPath.row]];
photoController.photoFilename = photoFilename;
}
}

In the above code, we first retrieve the current cell identifier and set it as the title of the
navigation bar. For those segues with showPhoto identifier, the photo view controller
will only display a single photo. Here we set the file name of the photo to be displayed.
Say, when user taps the Comments item, well show the comments_photo.jpg.

Compile and Test the Final App


Now compile and test the app again. Open the sidebar menu and tap the map item. Youll
be brought to the map view. Try to test other menu items and see what you get.

Summary
In this tutorial, we show you how to apply SWRevealViewController to implement a slideout navigation menu similar to the one in the Facebook app. If you do a search in GitHub,
you can find other sidebar solutions such as GHSidebarNav and ViewDeck. Youre free to
explore other libraries and see which is the best fit for your app. If youd like to learn how
to build the sidebar menu from scratch, Ray Wenderlich offers a great tutorial.
For your complete reference, you can download the full source code from GitHub. As
always, leave us comment and share your thought about the tutorial.
Note: If youre still using Xcode 5, you can download the project from here.