Material Components (MDC) help developers implement Material Design. Created by a team of engineers and UX designers at Google, MDC features dozens of beautiful and functional UI components and is available for Android, iOS, web and Flutter.

material.io/develop

In codelab MDC-103, you customized the color, elevation, typography, and shape of Material Components (MDC) to style your app.

A component in the Material Design system performs a set of predefined tasks and has certain characteristics, like a button. However, a button is more than just a way for a user to perform an action, it's also a visual expression of shape, size, and color that lets the user know that it's interactive, and that something will happen upon touch or click.

While the Material Design guidelines name many components, not all of them exist in MDC. You can still create these components yourself to achieve a customized style for your app, all using traditional code.

The Material Design guidelines describe components from a designer's point of view. They describe a wide range of basic functions available across platforms, as well as the anatomic elements that make up each component. For instance, a backdrop contains a back layer and its content, the front layer and its content, motion rules, and display options. Each of these components can be customized for each app's needs, use cases, and content. These pieces are, for the most part, traditional views, controls, and functions from your platform's SDK.

What you'll build

In this codelab, you'll add a backdrop to Shrine. It will filter the products shown in the asymmetrical grid by category. You'll be using:

How would you rate your level of experience building iOS apps?

Novice Intermediate Proficient

Download the starter codelab app

Download starter app

The starter app is located within the material-components-ios-codelabs-master/MDC-104/Swift/Starter directory. Be sure to cd into that directory before beginning.

...or clone it from GitHub

To clone this codelab from GitHub, run the following commands:

git clone https://github.com/material-components/material-components-ios-codelabs
cd material-components-ios-codelabs/MDC-104/Swift/Starter

Run the starter app

1. In Xcode open the workspace "Shrine.xcworkspace".

If you see the "Welcome to Xcode" window, click "Open another project...", navigate to the file and click open.

OR: Go to File > Open... and navigate to the file and click "Open".

OR: At the terminal enter:
open Shrine.xcworkspace

2. Run the app by pressing the play button at the top of the window.

Success! You should see Shrine's main interface running in the simulator.

A backdrop is the furthest back surface of an app, appearing behind all other content and components. It's composed of two surfaces: a back layer (which displays actions and filters) and a front layer (which displays content). You can use a backdrop to display interactive information and actions, such as navigation or content filters.

Change the root view controller to BackdropViewController

In AppDelegate.swift, change the root view controller in application(didFinishLaunchingWithOptions:) from HomeViewController to BackdropViewController.

  //TODO: Change the root view controller identifier to BackdropViewController
  let viewController =
        storyboard.instantiateViewController(withIdentifier: "BackdropViewController")

This controller has already been populated with a list of categories we will use to filter our products.

Well done! You've added a beautiful backdrop to Shrine's UI. Next, we'll bring the products back on top of our Backdrop..

Now we've set up our backdrop. Let's bring back the content that we concealed earlier.

Before we made any changes to Shrine in this codelab, the primary product content was located on the furthest back surface. By adding a backdrop, this content is now more emphasized because it appears in front of that backdrop.

Add a new layer

Now we'll add a front layer to hold all of the product content. Add the following to the end of viewDidLoad() in BackdropViewController.swift.

//TODO: Insert the HomeViewController into our BackdropViewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController =
  storyboard.instantiateViewController(withIdentifier: "HomeViewController")
self.insert(viewController)

Remove the duplicated AppBar

If you run the code, you will see two AppBars at the top. Since both of the view controllers have an AppBar, we are seeing both of them. Remove the AppBar from the embedded HomeViewController.

Remove the following lines from viewDidLoad() in HomeViewController.swift.

// AppBar Setup
//TODO Remove AppBar Setup in the following three lines
self.addChildViewController(appBar.headerViewController)
self.appBar.headerViewController.headerView.trackingScrollView = self.collectionView
appBar.addSubviewsToParent()

Add a shape

Let's style the front layer with a notch in the upper left corner. Material Design refers to this type of customization as a shape. Material surfaces can be displayed in different shapes. Shapes add emphasis and style to surfaces and can be used to express branding. Material shapes can have curved or angled corners and edges, and any number of sides. They can be symmetrical or irregular.

Just above where we inserted the HomeViewController let's change the containerView to a ShapedShadowedView from a standard UIView in the containerView initializer in BackdropViewController.swift.

//TODO: Change the following two lines from UIView to ShapedShadowedView
var containerView: ShapedShadowedView = {
  let view = ShapedShadowedView(frame: .zero)

Build and run the simulator and we'll see the proper interface, complete with the top left corner cut out of our product interface.

The buttons in our bottom layer are meant to be used to filter the displayed products. Let's reload our displayed products if the filter is changed.

Add a Notification observer to HomeViewController.swift. Add the following to the end of viewDidLoad().

//TODO: Register for the catalog changed notification
NotificationCenter.default.addObserver(self,
                                       selector: #selector(respondToCatalogNotification),
                                       name: Notification.Name(rawValue: "CatalogFilterDidChangeNotification"),
                                       object: nil)

Add a respondToCatalogNotification at the end of HomeViewController.m.

//TODO: Add notification Handler
// Catalog Update Handler reloads the collection view is the products have changed
  @objc func respondToCatalogNotification() {
    self.collectionView?.reloadSections([0])
  }

When we get a button tap on our filters, let's update our catalog. Add the following to BackdropViewController.swift in the didTapCategory() function.

//TODO: Set the catalog filter based on the button pressed
Catalog.categoryFilter = filter

Build and run. Press the settings button to toggle display of the Backdrop:

See the filter in action by pressing the "Clothing" button:

Over the course of these four codelabs, you've seen how to use Material Components to build unique, elegant user experiences that express a brand's personality and style.

Next steps

This codelab, MDC-104, completes this sequence of codelabs. You can explore more components and subsystems in the MDC iOS library.

I was able to complete this codelab with a reasonable amount of time and effort

Strongly agree Agree Neutral Disagree Strongly disagree

I would like to continue using Material Components in the future

Strongly agree Agree Neutral Disagree Strongly disagree