Skip to main content

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

Slide-out Sidebar Menu

Editor’s note #1: This post has been updated for Xcode 6 and iOS 8. The demo app now supports the latest version of SWRevealViewController.

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 we’ll show you how create a slide-out navigation menu similar to the one you find in the Facebook app.

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.

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, we’re not going to build the slide-out navigation menu from scratch. Instead, we’ll make use of a library called SWRevealViewController. Developed by John Launch, this excellent library provides a quick and easy way to put up a slide-out navigation menu and it’s available for free.

Read on and develop a demo app together.

A Glance at the Demo App

As usual, we’ll 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 we’ll build, let’s move on. You can create the Xcode project from scratch and design the user interface :

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
Importing the SWRevealViewController Library

As mentioned, we’ll use the free SWRevealViewController library to implement the slide-out 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, it’s 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, we’ve 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, you’ll 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 you’re 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 Frountpage).

Select the segue between SWRevealViewController and the navigation controller. In the attributes inspector, set the segue identifier to “sw_frount”. 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, you’ll see an app displaying the “News Frontpage”. But that’s it. You won’t see the sidebar menu when tapping the list button. We haven’t implemented the action method yet.

Open “MainViewController.m”, which is the controller class of “News Frontpage”. Add the following import statement:

#import "SWRevealViewController.h"

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

SWRevealViewController *revealViewController = self.revealViewController;
if ( revealViewController )
{
    [self.sidebarButton setTarget: self.revealViewController];
    [self.sidebarButton setAction: @selector( revealToggle: )];
    [self.view addGestureRecogniser:self.revealViewController.panGestureRecogniser];
}

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, it’ll call the revealToggle: method to display the sidebar menu. Lastly, we also add a gesture recogniser. 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. We’ll 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, we’ll design the sidebar menu right in the storyboard.

The first table cell of the Sidebar View Controller is defined with the title “iOSTutorial”. If you don’t 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 we’ll refer it later in our code.

Okay, let’s 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:

Change the “IOSTutorial” label of the second cell to “News”. Optionally, you can change the color of label to dark grey 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 38×38 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.

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 you’ve done everything correct, your sidebar view controller :

After completing the user interface, let’s implement the code for displaying the table cell. Select the “SidebarViewController.m” and add the following import statement:

#import "SWRevealViewController.h"

Next, declare the menuItems variable to store the cell identifier of the menu items:

@implementation SidebarViewController {
    NSArray *menuItems;
}

Update the viewDidLoad: method to the following:

- (void)viewDidLoad
{
    [super viewDidLoad];

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

The above code is very straightforward. We simply initialise 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)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return menuItems.count;
}

Lastly, change the cellForRowAtIndexPath: method to the following:

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

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 you’ll find a slide-out navigation menu with menu items.

Implementing Menu Item Selection

You’ve already built a visually appealing sidebar menu. There is still one thing left. For now, we haven’t 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, we’ll 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 we’re 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 we’ll 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”. We’ll 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"

Then insert the prepareForSegue: method to manage the transition.

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

// Set the title of navigation bar by using the menu items
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UINavigationController *destViewController = (UINavigationController*)segue.destinationViewController;
destViewController.title = [[menuItems objectAtIndex:indexPath.row] 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, we’ll 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. You’ll be brought to the map view. Try to test other menu items and see what you get.


Comments

Popular Posts

How I Reduced the Size of My React Native App by 85%

How and Why You Should Do It I borrowed 25$ from my friend to start a Play Store Developer account to put up my first app. I had already created the app, created the assets and published it in the store. Nobody wants to download a todo list app that costs 25mb of bandwidth and another 25 MB of storage space. So today I am going to share with you how I reduced the size of Tet from 25 MB to around 3.5 MB. Size Matters Like any beginner, I wrote my app using Expo, the awesome React Native platform that makes creating native apps a breeze. There is no native setup, you write javascript and Expo builds the binaries for you. I love everything about Expo except the size of the binaries. Each binary weighs around 25 MB regardless of your app. So the first thing I did was to migrate my existing Expo app to React Native. Migrating to React Native react-native init  a new project with the same name Copy the  source  files over from Expo project Install all de...

How to recover data of your Android KeyStore?

These methods can save you by recovering Key Alias and Key Password and KeyStore Password. This dialog becomes trouble to you? You should always keep the keystore file safe as you will not be able to update your previously uploaded APKs on PlayStore. It always need same keystore file for every version releases. But it’s even worse when you have KeyStore file and you forget any credentials shown in above box. But Good thing is you can recover them with certain tricks [Yes, there are always ways]. So let’s get straight to those ways. 1. Check your log files → For  windows  users, Go to windows file explorer C://Users/your PC name/.AndroidStudio1.4 ( your android studio version )\system\log\idea.log.1 ( or any old log number ) Open your log file in Notepad++ or Any text editor, and search for: android.injected.signing and if you are lucky enough then you will start seeing these. Pandroid.injected.signing.store.file = This is  file path where t...

React Native - Text Input

In this chapter, we will show you how to work with  TextInput  elements in React Native. The Home component will import and render inputs. App.js import React from 'react' ; import Inputs from './inputs.js' const App = () => { return ( < Inputs /> ) } export default App Inputs We will define the initial state. After defining the initial state, we will create the  handleEmail  and the  handlePassword  functions. These functions are used for updating state. The  login()  function will just alert the current value of the state. We will also add some other properties to text inputs to disable auto capitalisation, remove the bottom border on Android devices and set a placeholder. inputs.js import React , { Component } from 'react' import { View , Text , TouchableOpacity , TextInput , StyleSheet } from 'react-native' class Inputs extends Component { state = { ...