Customize your SWRevealViewController slide-out menu

Since the publication of the Facebook iOS app with the slide-out menu, this design pattern has become a quite standard way to implement a navigation menu that hides behind the main content view and only appears on user demand.

Slide-out menu implemented with the SWRevealViewController library

Slide-out menu implemented with the SWRevealViewController library

If you want to implement this behavior from scratch and deal with all details, there is a wonderful Ray Wenderlich’s tutorial that will get you to a totally configurable slide-out menu. If, on the other hand, you are happy with using an existing library, check out the SWRevealViewController, GHSidebarNav or ViewDeck repositories.

I chose to implement it using the SWRevealViewController library and with the support of the AppCoda’s post about how to add a slide-out menu in iOS apps. This tutorial is very useful, well written, and easy to follow. The only aspect that I missed was a section explaining how to customize it in order to change appearance, animations, timing, etc. The current post aims at solving this issue.

SWRevealViewController Overview

The SWRevealViewController library is just composed of a {.h,.m} tuple that include all necessary classes to implement the slide-out menu. A big advantage of this library is that it allows you to either (1) use it by coding all details by hand or (2) just follow a set of simple ‘click-based’ steps in the Interface Builder to create segues at storyboard level. I went for this last alternative.

StoryBoard constructed and file system used to implement the slide-out menu

StoryBoard constructed and file system used to implement the slide-out menu

The AppCoda tutorial that I used as reference focuses on the storyboard-based implementation but, as I mentioned before, it does not include the menu customization instructions. In order to deal with this issue, I subclassed the SWRevealViewController class (as EbcRevealVC) and just added the desired parameter settings in the viewDidLoad: method. I’m sure there are better ways to do it, but this one was fine for testing purposes. As a summary and for practical purposes, the next block of code details the all the parameters that I used to customize the slide-out menu appearance. Check the next section for a further discussion on the parameters.

- (void)viewDidLoad{
    [super viewDidLoad];
    [self customizeSlideOutMenu];
}

-(void) customizeSlideOutMenu{
    // INITIAL APPEARANCE: Configure the initial position of the menu and content views
    self.frontViewPosition = FrontViewPositionLeft; // FrontViewPositionLeft (only content), FrontViewPositionRight(menu and content), FrontViewPositionRightMost(only menu), see others at library documentation...
    self.rearViewRevealWidth = 150.0f; // how much of the menu is shown (default 260.0)

    // TOGGLING OVERDRAW: Configure the overdraw appearance of the content view while dragging it
    self.rearViewRevealOverdraw = 0.0f; // how much of an overdraw can occur when dragging further than 'rearViewRevealWidth' (default 60.0)
    self.bounceBackOnOverdraw = NO; // If YES the controller will bounce to the Left position when dragging further than 'rearViewRevealWidth' (default YES)

    // TOGGLING MENU DISPLACEMENT: how much displacement is applied to the menu when animating or dragging the content
    self.rearViewRevealDisplacement = 60.0f; // (default 40.0)

    // TOGGLING ANIMATION: Configure the animation while the menu gets hidden
    self.toggleAnimationType = SWRevealToggleAnimationTypeSpring; // Animation type (SWRevealToggleAnimationTypeEaseOut or SWRevealToggleAnimationTypeSpring)
    self.toggleAnimationDuration = 1.0f; // Duration for the revealToggle animation (default 0.25)
    self.springDampingRatio = 1.0f; // damping ratio if SWRevealToggleAnimationTypeSpring (default 1.0)

    // SHADOW: Configure the shadow that appears between the menu and content views
    self.frontViewShadowRadius = 10.0f; // radius of the front view's shadow (default 2.5)
    self.frontViewShadowOffset = CGSizeMake(0.0f, 2.5f); // radius of the front view's shadow offset (default {0.0f,2.5f})
    self.frontViewShadowOpacity = 0.8f; // front view's shadow opacity (default 1.0)
    self.frontViewShadowColor = [UIColor darkGrayColor]; // front view's shadow color (default blackColor)
}

Note that the method customizeSlideOutMenu: contains the parameter configuration that deals with: (1) the initial appearance of menu and content views, (2) the appearance and animation while the content and menu are being toggled, and (3) the shadow that the content view projects on the menu view. These are most of the appearance configuration parameters that can be set in the SWRevealViewController library according to the API described in the documentation. While a deeper study of the library code can result a more customizable configuration, these parameters might fit most of the developers requirements when using the SWRevealViewController library. For a more detailed configuration please refer to the repository website and dive into the library code.

Parameter description and examples

This section provides a plain-english description of the parameters together with some visual examples to help understanding what each one really does.

The initial appearance is set in frontViewPosition. With this parameter you are actually setting if the menu is initially shown or hidden. The picture below shows three common configurations with only the menu, only the content, and both at the same time.

Three different configurations for the frontViewPosition parameter

 

A related parameter is rearViewRevealWidth. As shown in the next picture, this one controls the amount of menu that is shown. Set a value close to 0 for a thin menu, or a value close to the screen width for a wide one.

Three different values set to rearViewRevealWidth

Three different values set to rearViewRevealWidth

 

There are several parameters that allow you to configure the appearance of the views while the menu and content are being toggled.

  • First, rearViewRevealOverdraw and bounceBackOnOverdraw control the possible overdraw that can happen while the content is being dragged. In practice, this overdraw occurs when the user drags the content towards the right side (assuming the menu is on the left). The content view will be displaced by this overdraw quantity beyond the rearViewRevealWidth. The parameter rearViewRevealOverdraw indicates the size of this overdraw; bounceBackOnOverdraw activates a back bounce – closing the menu – when the dragging goes beyond the limit of the overdraw. It is better if you try your own tests on this one so you can totally understand it.
  • And second, rearViewRevealDisplacement controls the displacement of the menu while the content is being dragged. That is, if we set it to 0.0, the menu does not move at all while the user drags the content. If we set the parameter to the same value of rearViewRevealWidth, the menu is displaced towards the left together with the content view as if the two views were glued. Personally, I like the intermediate effect with the menu moving at a slower pace than the content, hence setting a value to rearViewRevealDisplacement lower than rearViewRevealWidth. Next picture shows the three examples described assuming a rearViewRevealWidth equal to 160.

 

Three different values set to rearViewRevealDisplacement

Three different values set to rearViewRevealDisplacement

 

The menu is automatically shown or hidden when the user clicks the menu button in the navigation bar. There are three parameters that control the animation that results of this action.

  • toggleAnimationType controls the type of animation: SWRevealToggleAnimationTypeEaseOut or SWRevealToggleAnimationTypeSpring. As you might expect, the first one performs a ‘linear’ animation while the second one applies a more ‘harmonic’ or ‘spring’ animation where the views slides at lower speed when it is close to start and end positions. Although, it is really difficult to see the differences between the two sliding effects, I somehow prefer the spring version.
  • toggleAnimationDuration controls the duration time of the animation.
  • springDampingRatio controls the ‘bouncing’ effect of the spring-based animation. With a value lower than 1.0 you get the classical effect of a spring rebounding back and forth until it gets to its final position. Experimenting a little bit, I have found that setting this parameter to the default value of 1.0 results into a nice and smooth animation. I also noted that values larger than 1.0 did not make a big difference compared to setting it to 1.0.

 

And finally, the easy part: how to configure the shadow that the content view projects on top of the menu. This effect is controlled by 4 common shadow aspects: radius, offset, opacity and color. Each one is respectively controlled by the parameters frontViewShadowRadius, frontViewShadowOffsetfrontViewShadowOpacity, frontViewShadowColor. Next picture shows different combinations of this parameters to understand their effect. After some testing I decided that the last combination is the one I like the most.

Different shadow configurations setting the {radius, offset, opacity, color}

Different shadow configurations setting the {radius, offset, opacity, color}

 

If you use the SWRevealViewController library for your slide-out menu and happen to know more configuration possibilities, please leave a comment and I will be happy to complement the post.

  12 comments for “Customize your SWRevealViewController slide-out menu

  1. Dana
    09/04/2015 at 22:45

    How can I lower the opacity on the frontView when the menu is open?

    • ebc
      10/04/2015 at 10:18

      Hi Dana,
      it is not going to be easy because the API interface of the SWRevealViewController class seems not to offer this possibility.
      I’d subclass it and try to add the functionality in the right place, but this requires going into de code details of the library… If you find a solution, please share it and I’ll be happy to update the post!

  2. 26/05/2015 at 12:31

    Can you also point out how to get a right menu with storyboads.
    Thanks

  3. Pando
    31/05/2015 at 09:13

    Do you know a way to project a shadow from the menu onto the main view?

  4. 18/07/2015 at 04:26

    Is there any way to make the rearView appear on top of the frontView as below image in storyboard using Objective-C. I want to make the Front View navigation Fixed & make sidebar button static

  5. Shital
    18/03/2016 at 10:57

    My SWREVEL VIEW CONTROLLER not work when i am pushing from one view to another.

  6. mohammed
    11/01/2017 at 12:10

    Thanks a lot, but how to make the side-bar cover about 75% of main view and its’ buttons?

  7. thiru
    09/02/2017 at 11:28

    I want to remove shadow effect and I need one borderline

    • ebc
      10/02/2017 at 12:20

      Hi thiru, it is been a while since I last worked on iOS. If I have time I’ll try to give it a look and come back to you.
      edu

  8. Janki Jasani
    24/02/2017 at 07:36

    Is it possible to make the direction of slider drawn from right to left instead of left to right?? Please let me know about the feasibility. Thanks :)

Leave a Reply

Your email address will not be published. Required fields are marked *