Navigation Drawer

Open bugs badge

Navigation drawers provide access to destinations and app functionality, such as switching accounts. They can either be permanently on-screen or controlled by a navigation menu icon.

Bottom navigation example

Navigation drawers are recommended for:

  • Apps with five or more top-level destinations.
  • Apps with two or more levels of navigation hierarchy.
  • Quick navigation between unrelated destinations.
  • Contents

    Using navigation drawers

    While there is such a thing as a side navigation drawer, for example, we only provide bottom navigation drawers. Our bottom navigation drawer implementation is centered around MDCBottomDrawerViewController, a UIViewController subclass. MDCBottomDrawerViewController has a contentViewController property, whose view is displayed as the primary content of the drawer, as well as a headerViewController property, whose view is positioned above the content view controller and sticks to the top when the drawer is full-screen. For more information on implementing custom view controller classes see Apple's View Controller Programming Guide.

    MDCBottomDrawerViewController presentation makes use of the UIPresentationController subclass MDCBottomDrawerPresentationController, as well as MDCBottomDrawerTransitionController, which conforms to UIViewControllerTransitioningDelegate.

    If the primary content displayed in a bottom drawer is a UITableView or UICollectionView, specifically one that fills the content area, we recommend setting it as the trackingScrollView property for more performant scrolling.

    It is important that the view controller used as the headerViewController conforms to the MDCBottomDrawerHeader protocol, which implements the method -updateDrawerHeaderTransitionRatio:. This method provides transitionToTopRatio, a CGFloat that moves between 0 to 1 as the header view transitions from being positioned above the content to being sticky at the top of the screen. The transition begins as the header view begins to cover the status bar and safe area and ends once the header has reached the top of the screen.

    Example using the MDCBottomDrawerViewController with/without a header

    Swift

    let bottomDrawerViewController = MDCBottomDrawerViewController()
    bottomDrawerViewController.contentViewController = UIViewController()
    bottomDrawerViewController.headerViewController = UIViewController() # this is optional
    present(bottomDrawerViewController, animated: true, completion: nil)
    

    Objective-C

    MDCBottomDrawerViewController *bottomDrawerViewController = [[MDCBottomDrawerViewController alloc] init];
    bottomDrawerViewController.contentViewController = [UIViewController new];
    bottomDrawerViewController.headerViewController = [UIViewController new];
    [self presentViewController:bottomDrawerViewController animated:YES completion:nil];
    

    Example presenting a drawer without a header

    Swift

    let contentViewController = UIViewController()
    contentViewController.transitioningDelegate = MDCBottomDrawerTransitionController()
    contentViewController.modalPresentationStyle = .custom
    present(contentViewController, animated: true, completion: nil)
    

    Objective-C

    UIViewController *contentViewController = [UIViewController new];
    contentViewController.transitioningDelegate = [MDCBottomDrawerTransitionController new];
    contentViewController.modalPresentationStyle = UIModalPresentationCustom;
    [self presentViewController:contentViewController animated:YES completion:nil];
    

    Example using trackingScrollView

    Swift

    let contentViewController = UITableViewController()
    let bottomDrawerViewController = MDCBottomDrawerViewController()
    bottomDrawerViewController.contentViewController = contentViewController
    bottomDrawerViewController.headerViewController = UIViewController() # this is optional
    bottomDrawerViewController.trackingScrollView = contentViewController.view
    present(bottomDrawerViewController, animated: true, completion: nil)
    

    Objective-C

    UITableViewController *contentViewController = [UITableViewController new];
    MDCBottomDrawerViewController *bottomDrawerViewController = [[MDCBottomDrawerViewController alloc] init];
    bottomDrawerViewController.contentViewController = contentViewController;
    bottomDrawerViewController.headerViewController = [UIViewController new];
    bottomDrawerViewController.trackingScrollView = contentViewController.view;
    [self presentViewController:bottomDrawerViewController animated:YES completion:nil];
    

    Installing navigation drawers

    Add the following to your Podfile:

    pod 'MaterialComponents/NavigationDrawer'
    

    Then, run the following command:

    pod install
    

    Importing

    To import the component:

    Swift

    import MaterialComponents.MaterialNavigationDrawer
    

    Objective-C

    #import "MaterialNavigationDrawer.h"
    

    Making navigation drawers accessible

    While MDCBottomDrawerViewController supports the accessibility escape "Z" gesture, it is advisible that the content view controller provides its own dismiss action affordance. Note that it is the responsibility of the header and content view controllers to implement any custom accessibility behavior.

    Theming navigation drawers

    While MDCBottomDrawerViewController does have a theming extension, it should not be relied on for ensuring the content and header are themed correctly. It only sets properties like corner radius, scrim color, and handle color. To display sufficiently themed content with MDCBottomDrawerViewController you must make sure the content and header view controllers are themed independently.

    To make use of the bottom drawer theming extension you need to install it wth Cocoapods. First, add the following line to your Podfile.

    pod MaterialComponents/NavigationDrawer+Theming
    

    Then Run the installer.

    pod install
    

    Next, import the NavigationDrawer theming target, and call the correct theming method.

    Swift

    import MaterialComponents.MaterialNavigationDrawer
    import MaterialComponents.MaterialNavigationDrawer_Theming
    
    ...
     // Create a navigation drawer
    let bottomDrawerViewController = MDCBottomDrawerViewController()
     // Create or use your app's Container Scheme
    let containerScheme = MDCContainerScheme()
     // Theme the bottom drawer
    bottomDrawerViewController.applyTheme(withScheme: containerScheme)
    

    Objective-C

    #import "MaterialNavigationDrawer.h"
    #import "MaterialNavigationDrawer+Theming.h"
    
    ...
     // Create a navigation drawer
    MDCBottomDrawerViewController *bottomDrawerViewController = [[MDCBottomDrawerViewController alloc] init];
     // Create or use your app's Container Scheme
    MDCContainerScheme *containerScheme = [[MDCContainerScheme alloc] init];
     // Theme the bottom drawer
    [bottomDrawerViewController applyThemeWithScheme:containerScheme];