MvvmCross Hamburger menu for iOS

This has been deprecated. MvvmCross 5.0 changed the way this works. Please checkout the sample source. If you are on 4.4 this still works fine

There is a lot of demand for the so called “Hamburger” menu nowadays. On default it is supported by Android but not by iOS. Fortunately there are a lot of folks on github who have made a hamburger menu for iOS and these implementations have been made available for Xamarin and MvvmCross. This article will show how easy it is to implement a hamburger menu for a MvvmCross based project.

The result out of this post will be a basic iOS hamburger menu for MvvmCross which you can customize to your heart’s contents. For a complete customized sample please see the github page: https://github.com/MarcBruins/MvvmCross-Sidebar-Sample/

Xamarin sidebar vs JASidePanels

In MvvmCross iOS there are two existing packages which can be used. Xamarin Sidebar and JASidePanels. The difference is mainly UI based. Both the JASidepanels and the Xamarin Sidebar have the ability to create two menus. One for the left side and one for the right. Furthermore JASidepanels uses a UINavigationBar on the Menu view and Xamarin sidebar does not.

The nice thing that the iOSSupport package has to offer is that you can switch implementations by editing only one line of code!

JASidePanels Xamarin Sidebar
JASidepanel Sample apr.-18-2016 20-33-31

Setup

Before we start we need to setup a MvvmCross solution with a Core project and a iOS project. If you don’t know how, then check out out this video by Jonathan Roux. The first two minutes will show you exactly how you should start.

For the same steps but in text checkout his blogpost: http://jonathanroux.com/2016/02/09/mvvmcross-4-and-xamarin-project-setup/.

Usage

By now you should have a Core project and an iOS project and we can start implementing the menu. We will be using the Xamarin Sidebar at first and later on i will explain how to add the JASidePanels component.

We are going to create the Views and a Viewmodels for the content and also for the menu. To let MvvmCross know that is indeed a hamburger menu we are going to add attributes in our views. That should be all. Lets start!

ContentViewModel 

This will be the main ViewController which will hold the content that you want to show in your app (duh).

  1. Add a new class to your ViewModels called “ContentViewModel”
  2. Let the class extend “MvxViewModel”
  3. Add a public function called ShowMenu that navigates to the MenuViewModel

The result should be something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;
using MvvmCross.Core.ViewModels;
 
namespace SideBarSample.Core.ViewModels
{
    public class ContentViewModel : MvxViewModel
    {
        public ContentViewModel ()
        {
        }
 
        public void ShowMenu()
        {
            ShowViewModel<MenuViewModel>();
        }
    }
}

The project will not compile saying that there is no MenuViewModel. That is correct, our next step is to fix this error by adding the MenuViewModel.

MenuViewModel

The menuviewmodel will be the viewmodel for our menu.

  1. Add a new class to your ViewModels called “MenuViewModel”
  2. Let the class extend “MvxViewModel”

The result should be something like this:

1
2
3
4
5
6
7
8
9
10
11
12
using System;
using MvvmCross.Core.ViewModels;
 
namespace SideBarSample.Core.ViewModels
{
    public class MenuViewModel : MvxViewModel
    {
        public MenuViewModel ()
        {
        }
    }
}

Appstart

The last thing we will do in the Core project is setting the ContentViewModel as the start ViewModel of our app. This is done by changing the App.cs file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
namespace SideBarSample.Core
{
    public class App : MvvmCross.Core.ViewModels.MvxApplication
    {
        public override void Initialize()
        {
            CreatableTypes()
                .EndingWith("Service")
                .AsInterfaces()
                .RegisterAsLazySingleton();
 
            RegisterAppStart<ViewModels.ContentView>();
        }
    }
}

Your core project should look something like this now.

Sidebar core project

Boom! That should be all for the core project! Lets move on the the iOS project and create the corresponding views!

 Views

We are going to create our views by using .xibs but if you rather have storyboards that should also be possible. Before we start adding them we need to install the nuget packages. After that we will be creating the views and bind them to the viewmodel just like you would do it normally. Finally we will be using the MvxPanelPresentation attribute and the XamarinSidebar package to create the hamburger menu!

Add xamarin sidebar

In Xamarin studio right click your iOS project and go to “Add” -> “Add Nuget Packages”

  • Search for “Xamarin Sidebar” and select the package
  • Finally click “Add Package” and make sure MvvmCross iOS Support is included. This will install the XamarinSidebar package and the iOSSupport core

Add Xamarin sidebar package

MvxPanelPresentation

There are a few core concepts about MvxPanelPresentation that are important to understand. MvxPanelPresentation is an attribute that allows you to define the nature of the view you are creating by defining its parameters. It will look something like this:

1
2
[MvxPanelPresentation(MvxPanelEnum.Center, MvxPanelHintType.ResetRoot, true)]
public partial class CenterView : MvxViewControllerContentViewModel
MvxPanelEnum

The MvxPanelEnum will place the view on the side that has your preference.

1
2
3
4
5
6
7
public enum MvxPanelEnum
{
    None,
    Center,
    Left,
    Right
}

By setting it to Right the menu will be displayed on the right side. By setting it to left it will be displayed on the left. The JASidepanel supports both right and left. The contentview will be the center of your app and will use the Center enum value.

MvxPanelHintType

MvxPanelHintType is an enum that tells something about the behaviour of the view.

ResetRoot The ResetRoot will replace any existing contentview and make the new view with this value the root.
PopToRoot The PopToRoot will make sure that the navigation stack views pops the view on the stack until it reaches the root. After that the view will be displayed as the rootview.
ActivePanel The views attributed with the ActivePanel value will be pushed on to the navigation stack. You can think of it as a detail view which has the back arrow on the top left corner.
showPanel

A boolean value if you want to show the panel or not.

ContentView

First lets create our contentview:

  1. Right click on your views folder in your iOS project and add a new ViewController called “ContentView
  2. Extend MvxViewController and let MvvmCross know that it belongs to the ContentViewModel by setting the generic parameter.
  3. Add the MvxPanelPresentationAttribute
  4. In the MvxPanelPresentationAttribute set MvxPanelEnum to Center
  5. In the MvxPanelPresentationAttribute set MvxPanelHintType to ResetRoot
  6. Set the ShowPanel value to true
  7. Call the ViewModel.ShowMenu() function from within you ViewDidLoad.

The result:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[MvxPanelPresentation(MvxPanelEnum.Center, MvxPanelHintType.ResetRoot, true)]
public partial class CenterView : MvxViewController<ContentViewModel>
{
 
    public CenterView ()
    {
    }
 
    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();
        // Perform any additional setup after loading the view, typically from a nib.
        ViewModel.ShowMenu ();
    }
}

MenuView

And now our final view. This view is going to be very basic but you can customize it anyway you want. Note that you can create a left and a right menu view. We will be creating a left menuview for now but you can repeat this process for a right side menu.

  1. Right click on your views folder in your iOS project and add a new ViewController called “MenuView
  2. Extend MvxViewController and let MvvmCross know that it belongs to the MenuViewModel by setting the generic parameter.
  3. Add the MvxPanelPresentationAttribute
  4. In the MvxPanelPresentationAttribute set MvxPanelEnum to Left
  5. In the MvxPanelPresentationAttribute set MvxPanelHintType to ActivePanel
  6. Set the ShowPanel value to false

The MenuView.cs:

1
2
3
4
5
6
7
8
[MvxPanelPresentation(MvxPanelEnum.Left, MvxPanelHintType.ActivePanel, false)]
public partial class MenuView : MvxViewController<MenuViewModel>
{
    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();
    }
}

We’re almost done!

The last thing we should do is to tell MvvmCross that is should use the Presenter that handles the navigation:

Setup.cs:

1
2
3
4
5
6
7
8
9
public class Setup : MvxIosSetup
  {
     //......... the default methods
 
      protected override IMvxIosViewPresenter CreatePresenter()
      {
          return new MvxSideBarPresenter((MvxApplicationDelegate)ApplicationDelegate, Window);
      }
  }

If you want to use JASidepanels just add the nuget package and change the presenter:

1
2
3
4
5
6
7
8
9
public class Setup : MvxIosSetup
  {
     //......... the default methods
 
      protected override IMvxIosViewPresenter CreatePresenter()
      {
          return new MvxSidePanelsPresenter((MvxApplicationDelegate)ApplicationDelegate, Window);
      }
  }

Thats it, were done! We have create a hamburger menu that we can fully customize and we can switch implementations by changing only one line of code. Now go ahead and make some beautiful menu’s!