MDC-104 iOS: Material Advanced Components (Swift)

1. Introduction

logo_components_color_2x_web_96dp.png

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.

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.

While the Material Design guidelines name many components, not all of them are good candidates for reusable code and therefore aren't found in MDC. You can create these experiences yourself to achieve a customized style for your app, all using traditional code.

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:

  • View Controller Containment
  • Shape
  • Notifications

708420b92b846e6e.png 7bdd59d26b357a52.png

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

Novice Intermediate Proficient

2. Set up your development environment

Download the starter codelab 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/Shrine

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.Note: Screenshots are generated from building on an iPhone 6s.

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

3. Add the backdrop menu

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.

ceae0bfe1499cfb8.png

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.

4. Embed the Products View Controller into the Backdrop View Controller

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)

61f2327589ad2a20.png

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 six lines
self.addChildViewController(self.appBarViewController)
self.view.addSubview(self.appBarViewController.view)
self.appBarViewController.didMove(toParentViewController: self)

// Set the tracking scroll view.
self.appBarViewController.headerView.trackingScrollView = self.collectionView

72edc3ec29c976b.png

Add a shape scheme to your application

In ApplicationScheme.swift, modify the following lines:

public let shapeScheme: MDCShapeScheming = {
  let scheme = MDCShapeScheme()
    scheme.largeComponentShape = MDCShapeCategory(cornersWith: .cut, andSize: 20)
  return scheme
}()

Add a shape and apply it to the backdrop

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. Then we apply the applications shape scheme on the ShapedShadowedView, specifically the top left corner of the backdrop.

Remove

  //TODO: Change the container view into a ShapedShadowedView and apply the shape.
  let view = UIView(frame: .zero)

and replace it with

  //TODO: Change the following line from UIView to ShapedShadowedView
  let view = ShapedShadowedView(frame: .zero)
  let shapeGenerator = MDCRectangleShapeGenerator()
  shapeGenerator.topLeftCorner =    
      ApplicationScheme.shared.shapeScheme.largeComponentShape.topLeftCorner
  view.shapeGenerator = shapeGenerator

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

ab9a395b89c36925.png

5. Add filtering

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.swift.

//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:

d36aad30bbea41e.png

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

cd40beba39d1bb23.png

6. Recap

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