MDC-103 iOS: Material Theming with Color, Shape, Elevation and Type (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 codelabs MDC-101 and MDC-102, you used Material Components (MDC) to build the basics of an app called Shrine, an e-commerce app that sells clothing and home goods. This app contains a user flow that starts with a a login screen and takes the user to a home screen that displays products.

The recent expansion of Material Design gives designers and developers increased flexibility to express their product's brand. You can now use MDC to customize Shrine and reflect its unique style more than ever.

What you'll build

In this codelab, you'll customize Shrine to reflect its brand using:

  • Color
  • Typography
  • Layout

a34ae096aeef67c0.png

55c17631cb0f1229.png

MDC iOS components and subsystems used in this codelab:

  • Themes
  • Color
  • Typography

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-103/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-103/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 login screen. Press "Next" to get to the home screen. It should look like the image below.

543cd459652be0f6.png

While the app is functional, let's make it match the Shrine brand by changing its color and typography.

3. Change the color

This color theme has been created by a designer with custom colors (shown in the image below). It contains colors that have been selected from Shrine's brand and applied to the Material Theme Editor, which has expanded them to create a fuller palette. (These colors aren't from the 2014 Material color palettes.)

The Material Theme Editor has organized them into shades labelled numerically, including labels 50, 100, 200, .... to 900 of each color. Shrine only uses shades 50, 100, and 300 from the pink swatch and 900 from the brown swatch.

wlq5aH94SfU47pcalUqOSK57OCX4HnJJTpMVzVrBZreUOE-CrkX2akKrnTbgwf6BQNMBi-nn16jpgQHDeQZixTCeh1A0qTXcxDMTcc2-e6uJg0LPjkXWEVlV7cwS0U1naqpnHToEIQ 1HLdzGp-TIhg2ULijquMw_KQdk18b080CVQN_oECAhiCnFI11Nm3nbcsCIXvZBXULMajAW9NEmGZ7iR_j-eEF6NiODuaike96xVpLwUIzfV4dzTg9uQHsmNG-BDTOd04e6_eRLs--Q

Let's change the color of the navigation drawer to reflect that color scheme. We'll do this be instantiating a default ColorScheme object and modifying its properties to match our designer's color scheme.

Set the application's colors

In ApplicationScheme.swift, add the following lines to the colorScheme initialization:

//TODO: Customize our app Colors after this line
scheme.primaryColor =
  UIColor(red: 252.0/255.0, green: 184.0/255.0, blue: 171.0/255.0, alpha: 1.0)
scheme.primaryColorVariant =
  UIColor(red: 68.0/255.0, green: 44.0/255.0, blue: 46.0/255.0, alpha: 1.0)
scheme.onPrimaryColor =
  UIColor(red: 68.0/255.0, green: 44.0/255.0, blue: 46.0/255.0, alpha: 1.0)
scheme.secondaryColor =
  UIColor(red: 254.0/255.0, green: 234.0/255.0, blue: 230.0/255.0, alpha: 1.0)
scheme.onSecondaryColor =
  UIColor(red: 68.0/255.0, green: 44.0/255.0, blue: 46.0/255.0, alpha: 1.0)
scheme.surfaceColor =
  UIColor(red: 255.0/255.0, green: 251.0/255.0, blue: 250.0/255.0, alpha: 1.0)
scheme.onSurfaceColor =
  UIColor(red: 68.0/255.0, green: 44.0/255.0, blue: 46.0/255.0, alpha: 1.0)
scheme.backgroundColor =
  UIColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 1.0)
scheme.onBackgroundColor =
  UIColor(red: 68.0/255.0, green: 44.0/255.0, blue: 46.0/255.0, alpha: 1.0)
scheme.errorColor =
  UIColor(red: 197.0/255.0, green: 3.0/255.0, blue: 43.0/255.0, alpha: 1.0)

Apply the colors to the home screen

Now that we've updated our application's color scheme, we'll use existing properties and a themer to apply the colors to our interface.

Add the code to HomeViewController in HomeViewController.swift near the end of the viewDidLoad method:

// TODO: Theme our interface with our colors
self.view.backgroundColor = ApplicationScheme.shared.colorScheme
.surfaceColor
self.collectionView?.backgroundColor = ApplicationScheme.shared.colorScheme
.surfaceColor
MDCAppBarColorThemer.applyColorScheme(ApplicationScheme.shared.colorScheme
, to:self.appBarViewController)

Build and run. Your home screen should now look like this: b95603875b8b7c6c.png

Let's change the color of the login screen to match our color scheme.

Add the colors to the login screen

Add the code to LoginViewController in LoginViewController.swift near the end of the viewDidLoad method:

// TODO: Theme the interface with our colors
let colorScheme = ApplicationScheme.shared.colorScheme
self.view.tintColor = colorScheme.onSurfaceColor
self.view.backgroundColor = colorScheme.surfaceColor
self.logoImageView.tintColor = colorScheme.onSurfaceColor
self.titleLabel.textColor = colorScheme.onSurfaceColor
MDCTextFieldColorThemer.applySemanticColorScheme(colorScheme,
                                                 to: self.usernameTextFieldController)
MDCTextFieldColorThemer.applySemanticColorScheme(colorScheme,
                                                 to: self.passwordTextFieldController)
MDCButtonColorThemer.applySemanticColorScheme(colorScheme,
                                              to: self.cancelButton)
MDCButtonColorThemer.applySemanticColorScheme(colorScheme,
                                              to: self.nextButton)


Build and run. Your login screen should now look like this: a34ae096aeef67c0.png

4. Modify typography and label styles

In addition to color changes, your designer has also given you specific typography to use in the app. (We're including a custom font inside the app.) Let's add that to the home screen too.

Set the custom font in the Application Scheme

In ApplicationScheme.swift, update the following code in the typographyScheme init:

//TODO: Add our custom fonts after this line
let fontName = "Rubik"
scheme.headline5 = UIFont(name: fontName, size: 24)!
scheme.headline6 = UIFont(name: fontName, size: 20)!
scheme.subtitle1 = UIFont(name: fontName, size: 16)!
scheme.button = UIFont(name: fontName, size: 14)!

Update the AppBar typeface

In HomeViewController.swift, update the following code at the end of the viewDidLoad() function.

// TODO: Theme our interface with our typography
MDCAppBarTypographyThemer.applyTypographyScheme(ApplicationScheme.shared.typographyScheme
, to: self.appBarViewController)

Style the item cells

To adjust the font and alignment, add the following code to the configureCell method in ProductCell.swift:

//TODO: Set custom font based on our ApplicationScheme and center align text
self.nameLabel.font = ApplicationScheme.shared.typographyScheme.subtitle1
self.priceLabel.font = ApplicationScheme.shared.typographyScheme.subtitle1

self.nameLabel.textAlignment = .center
self.priceLabel.textAlignment = .center

Update the same configureCell method to disable the rounded corners and stroke outline.

    //TODO: Set to 0 to disable the curved corners
    self.cornerRadius = 0.0;

    //TODO: Set Border Width to 0 to disable the stroke outline
    self.setBorderWidth(0.0, for:.normal)
    self.setBorderColor(.lightGray, for: .normal)

Build and run. Your home screen should now look like this:

b134c6c2297fcd75.png

Let's change the typography of the login screen to match.

Change the typeface of the login screen

In LoginViewContoller.swift, modify the viewDidLoad method with the following lines:

// TODO: Theme the interface with our typography
let typographyScheme = ApplicationScheme.shared.typographyScheme
titleLabel.font = typographyScheme.headline5
MDCTextFieldTypographyThemer.applyTypographyScheme(typographyScheme,
                                                   to: usernameTextFieldController)
MDCTextFieldTypographyThemer.applyTypographyScheme(typographyScheme,
                                                   to: passwordTextFieldController)
MDCButtonTypographyThemer.applyTypographyScheme(typographyScheme,
                                                to: cancelButton)
MDCButtonTypographyThemer.applyTypographyScheme(typographyScheme,
                                                to: nextButton)

Build and run. Your login screen should now look like this: a34ae096aeef67c0.png

5. Change the layout

Next, let's change the layout to show the cards at different aspect ratios and sizes, so that each card looks unique from the others. We'll also change the scrolling direction from vertical to horizontal.

Modify the CollectionView Layout

We're providing a custom UIViewCollectionLayout in the CustomLayout class. For more information on implementing a custom collection layout, see Apple's documentation.

In HomeViewController.swift, add the code to the end of the viewDidLoad method:

// TODO: Set layout to our custom layout
self.collectionView?.collectionViewLayout = CustomLayout()

25333fefd2e22d3f.png

6. Try another theme

Color is a powerful way to express your brand, and a small change in color can have a large effect on your user experience. To test this out, let's see what Shrine would look like if the color scheme of the brand were completely different.

Change the scheme to a variant

In ApplicationScheme.swift, modify the colorScheme initialization.

//TODO: Customize our Colors after this line
scheme.primaryColor =
  UIColor(red:0.36, green:0.06, blue:0.29, alpha:1.0)
scheme.onPrimaryColor =
  UIColor(red:1.00, green:1.00, blue:1.00, alpha:1.0)
scheme.secondaryColor =
  UIColor(red:0.89, green:0.02, blue:0.15, alpha:1.0)
scheme.onSecondaryColor =
  UIColor(red:1.00, green:1.00, blue:1.00, alpha:1.0)
scheme.surfaceColor =
  UIColor(red:1.00, green:1.00, blue:1.00, alpha:1.0)
scheme.onSurfaceColor =
  UIColor(red:0.00, green:0.00, blue:0.00, alpha:1.0)
scheme.backgroundColor =
  UIColor(red:0.96, green:0.89, blue:0.93, alpha:1.0)
scheme.onBackgroundColor =
  UIColor(red:0.00, green:0.00, blue:0.00, alpha:1.0)
scheme.errorColor =
  UIColor(red:0.99, green:0.59, blue:0.15, alpha:1.0)

In ApplicationScheme.swift, modify the typographyScheme initialization to switch from Rubik to Chalkduster.

//TODO: Customize our Fonts after this line
let fontName = "Chalkduster"

Build and run. The new theme should now appear.

915ebcefaa755d4c.png

371c50bfb0955e99.png

The colors and typography are very different! Let's revert this change before moving on to 104.

7. Recap

By now, you've created an app that resembles the design specifications from your designer.

Next steps

You've now used the following MDC components: theme, color, and typography. Explore more components and subsystems in the MDC iOS library.

What if your planned app design contains elements that don't have components in the MDC library? In MDC-104: Material Design Advanced Components, we will go over how to create custom components using the MDC library to achieve a specific look.

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