In this tutorial we will learn to implement Facebook’s Paper app like menu using Swift 2 in XCode 7.1

Facebook's Paper Menu

 

Getting started

Open Xcode and create a new project by choosing the Single View Application template. Choose iPhone under “Devices”. Choose Swift as main language.

Xcode 7.1

Next, you are presented with the page to set many of the important aspects of your project, particularly your “Product Name” and “Language”, which will be Swift, of course.

Product Name is pretty self-explanatory.  The organization name can be whatever you want, but it probably should the the company or name you are releasing your apps under. We will not have CoreData, Unit Tests or UI Tests usage in this tutorial so uncheck the box and Swift is the main language to be used.

When you click next, you will be presented with a save dialog, asking where you want to save your project.  Wherever you save it, a folder will be created with your app’s name, and inside will be the Xcode project, and a folder for each target your app has (which is going to be the app itself, and a test target right now).  You also have the option to create a Git repository for your project either locally or on a server.

After you click the “Create” button, the files for your project are generated and you are probably looking at your AppDelegate.swift file.

Adding custom files

This tutorial requires a custom menu controller file to be imported into our project for the paper app like menu. This class file is made freely available to us by soyzamudio on Github. You can download the class file from here. (Download Link). All credits go to soyzamudio for this conversion of GTAppMenuController class files to Swift. The download link mentioned above provides you with necessary Class file which we will use into our project in future. Also download 2 images which we will be using in this tutorial for better visuals. (Download Link). Extract the images and drag all the files into our Xcode project.

Setting up the Storyboard

Now we’ll set up the storyboard.  In this app we will only focus on a home screen & menu screen transition.

Open Main.storyboard and you will see a single ViewController.

  1. Select the View Controller, Press Editor on the menu > Embed in > Navigation Controller
  2. Embed Navigation ControllerAdd a new Cocoa Touch Class file by pressing cmd + n and name it MainMenuViewController.
  3. Remove the entry point (an arrow pointing to the navigation view controller). Select the newly dragged viewController and go to the attributes inspector. Tick the is Initial View Controller option which will make this view as the starting point.
  4. We will then set the class of the view controllers from the identity inspector on the right. View Controller has default class set and hence we won’t be changing it.
  5. Select the navigation controller and set it’s class to SwiftAppMenuController (the file which we recently downloaded from dropbox). Also change it’s Storyboard ID to ” home ” which we will be using in future.
  6. Now select the other ViewController that we dragged earlier and set it’s class to MainMenuViewController. Also change it’s Storyboard ID to ” menu ” which we will be using in future.
  7. We will add UIImage View from the object library to both the ViewControllers, it will show an image that presents the UI of any regular application.
  8. Set the UIImageView of home view to home.png file and UIImageView of menuView to menu.jpeg. This fast way was chosen to showcase some good UI just to let you know how it will look on a well developed application.

The storyboard view controller should look like the image shown below:

Storyboard

 

Setting up the AppDelegate code :

Open the AppDelegate.swift file and add some lines in the didFinishLaunchingWithOptions function:

    var window: UIWindow?
    var backWindow: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        
        let strybd:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let back:MainMenuViewController = strybd.instantiateViewControllerWithIdentifier("menu") as! MainMenuViewController
        
        self.backWindow = UIWindow(frame: UIScreen.mainScreen().bounds)
        self.backWindow!.rootViewController = back
        backWindow?.makeKeyAndVisible()
        
        let front:SwiftAppMenuController = strybd.instantiateViewControllerWithIdentifier("home") as! SwiftAppMenuController
        
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        self.window!.rootViewController = front
        self.window!.makeKeyAndVisible()
        
        return true

    }

Let’s understand the code written above. First we create an instance of the UIStoryboard with name Main (which is our storyboard in the project). We then create an instance of MainMenuViewController and SwiftAppMenuController using instantiateViewControllerWithIdentifier method. These controllers are set to the backWindow and window’s rootViewController. Window is the main screen our app will present and when app finishes it’s launching the SwiftAppMenu controller will be loaded in front with the MainMenu view at the back of the main window.

Setting up the ViewController code :

Open the ViewController.swift file and add some lines in the viewDidLoad function:

var navController = SwiftAppMenuController()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        self.navigationController?.navigationBar.translucent = false
        self.title = "Paper Menu"
        
      //Present Menu with a button in Navbar
        var rightItem: UIBarButtonItem = UIBarButtonItem()
        rightItem = UIBarButtonItem(title: "Menu", style: .Plain, target: self, action: "menuPressed")
        self.navigationItem.rightBarButtonItem = rightItem
        
        navController = self.navigationController as! SwiftAppMenuController
        navController.setNavigationBarHidden(true, animated: false) // Currently navBar hidden is true
        
        let swipeDown = UISwipeGestureRecognizer(target: self, action: "respondToSwipeGesture:")
        swipeDown.direction = UISwipeGestureRecognizerDirection.Down
        self.view.addGestureRecognizer(swipeDown)
        
        let swipeUp = UISwipeGestureRecognizer(target: self, action: "respondToSwipeGesture:")
        swipeUp.direction = UISwipeGestureRecognizerDirection.Up
        self.view.addGestureRecognizer(swipeUp)
    }

In the above lines we create an instance of SwiftAppMenuController as navController. We then apply some fancy stuff to the navigation bar with title and translucent properties. The next lines add a right bar button item to the navbar which will activate the menu using the rightBarButtonItem method. This was implemented for those who want a navbar button menu activation. But in this tutorial we will hide the navbar and initiate the menu by swiping down the home screen. This will be achieved detecting a swipeDown & swipeUp gesture using UISwipeGestureRecognizer. First we create an instance of UISwipeGestureRecognizer and then detect it’s direction. When a particular direction is detected the action calls a function “respondToSwipeGesture:” which we have specified while creating the instance.

The respondToSwipeGesture function will look like this:

func respondToSwipeGesture(gesture: UIGestureRecognizer) {
        
        if let swipeGesture = gesture as? UISwipeGestureRecognizer {
            
            switch swipeGesture.direction {
            case UISwipeGestureRecognizerDirection.Down:
                print("Swiped down")
                menuPressed()
            case UISwipeGestureRecognizerDirection.Up:
                print("Swiped up")
                menuPressed()
            default:
                break
            }
        }
    }

The code above gets the UIGestureRecognizer passed from the viewDidLoad and the switch statement accordingly runs the up or down directed gesture. Now what is this menuPressed() function, we also saw the same in the viewDidLoad func in the rightBarButtonItem. Well this function calls openAndCloseMenu method from the SwiftAppMenuController class. It calls the menu by pushing the current view down. If the menu is present it will push the homeView to front and hide the menu. So basically it acts as a toggle for the menu.

It looks as follows:

func menuPressed() {
        navController.openAndCloseMenu()
    }

Last but not the least, since we have dark UI elements used everywhere we need to change the statusbar color to LightContent. To achieve this we perform the following instructions:

  1. Open your info.plist and insert a new key named “View controller-based status bar appearance” to NO
  2. Now we put the following code in the application(_:didFinishLaunchingWithOptions:) method of the AppDelegate
    UIApplication.sharedApplication().statusBarStyle = .LightContent
  3. This will affect all the view controllers to change the statusbar content color to white.

This is it! We have just mastered creating a Facebook’s Paper app like menu.

Running the App

So now you run the app with the big “Play” button in the top left of Xcode.  You then need to set what device to run the app on.  You can select a physical device (if you have a paid developer license).  Otherwise, or even just for simpler testing, you can run it in the simulator.  Choose the simulated device to run it on from the same menu.

Then wait a bit while the simulator loads.  Mine took about 20-25 seconds to load.  Then click on a menu button and watch the magical menu dropdown occur!

Here is the source code on Github for the tutorial above !

I hope you found this article helpful.  If you did, please don’t hesitate to share this post on Twitter or your social media of choice.  The blog is still pretty new, and every share helps.  Of course, if you have any questions, don’t hesitate to contact me on Twitter @swifty_os, and I’ll see what I can do.  Thanks!

Advertisements