Skip to content

Latest commit

 

History

History
356 lines (265 loc) · 13.8 KB

File metadata and controls

356 lines (265 loc) · 13.8 KB

Cards

Open bugs badge

Cards contain content and actions about a single subject.

An arrangement of cards containing various charts and graphs

Contents


Using cards

Installing

In order to use Material cards, first add the Cards subspec to your Podfile:

pod MaterialComponents/Cards

Then, run the installer:

pod install

After that, import the relevant target or file.

Swift

import MaterialComponents.MaterialCards

Objective-C

#import "MaterialCards.h"

Cards Classes

On iOS, the Cards component offers two implementations to choose from, MDCCard and MDCCardCollectionCell.

MDCCard

MDCCard subclasses UIControl. Subclassing MDCCard allows you to create cards that match the Material spec.

MDCCard uses UIControlState to represent state. Its styling changes depending on whether its state is .normal or .highlighted.

MDCCard allows the following properties to be customized:

  • The border width for a specific state
  • The border color for a specific state
  • The shadow elevation for a specific state
  • The shadow color for a specific state
  • The corner radius for the card

MDCCardCollectionCell

MDCCardCollectionCell subclasses UICollectionViewCell. Subclassing MDCCardCollectionCell allows you to have Material cards as cells in your UICollectionView.

MDCCardCollectionCell has its own notion of state, MDCCardCellState, which is tied to the UICollectionViewCell highlighted and selected properties.

In addition to those offered by MDCCard, MDCCardCollectionCell offers the following customization options:

  • Changing the image that appears in the Selected state.
  • Changing the image tint color that appears in the Selected state.

Making cards accessible

Accessibility best practices depend on whether you are using an MDCCard or an MDCCardCollectionCell.

MDCCardaccessibility

The nested elements in an MDCCard are available to assistive technologies without additional customization. However, additional setup may be needed to accommodate the following scenarios:

Cards with Images

Images may have additional context beyond text that is already presented on the card. For example, news article images can benefit from an accessibilityLabel describing their content.

Swift

articleImageView.isAccessibilityElement = true
articleImageView.accessibilityLabel = "Event or scene description"

Objective-C

articleImageView.isAccessibilityElement = YES;
articleImageView.accessibilityLabel = @"Event or scene description";

Cards with "star ratings"

Star or rating images should have accessibilityLabel property values describing their purpose and accessibilityValue property values describing their rating value.

Swift

ratingView.isAccessibilityElement = true
ratingView.accessibilityLabel = "Average customer rating, out of " + 
  "\(MDCProductRating.maximumValue) stars"
ratingView.accessibilityValue = (String)product.averageRating

Objective-C

ratingView.isAccessibilityElement = YES;
ratingView.accessibilityLabel = [NSString stringWithFormat:@"Average customer" +
  " rating, out of %d stars", MDCProductRating.maximumValue];
ratingView.accessibilityValue = @(product.averageRating).stringValue;

Cards whose contents should be read in a specific order

Primary content or actions that appear lower on the screen will be read last by assistive technologies, sometimes after longer or non-primary content. To change the order, or group elements together, you can make the card an accessibility container by adopting the UIAccessibilityContainer protocol. Grouping and order is controlled by creating as many UIAccessibilityElement elements as needed, and returning them in the desired order.

MDCCardCollectionCell accessibility

Since assistive technologies visit all cards in a collection in a sequential order, it is often easier to distinguish between elements that belong to different cards by aggregating all the card's information so the card is read as a single sentence. This can be done by setting an appropriate accessibilityLabel for the card. Additionally, set the card's isAccessibilityElement to true. Cards are a container element and setting isAccessibiltyElement for a container turns off individually selecting its subelements.

Swift

card.isAccessibilityElement = true
card.accessibilityLabel = "Location \(userLocation.name) is popular with users " +
  "who enjoy \(userLocation.popularActivityMatchingUserProfile(userProfile))"

Objective-C

card.isAccessibilityElement = YES;
card.accessibilityLabel = [NSString 
  stringWithFormat:@"Location %@ is popular with users who enjoy %@",  
  userLocation.name, 
  userLocation.popularActivityMatchingUserProfile(userProfile)];

Types

Card

Card with sample image and buttons

While iOS has two different implementations for Cards, there is really only one type of card from the design perspective. The example above could be built using either an MDCCard or an MDCCardCollectionCell. Here is an example class that does it with MDCCard.

MDCCard example

MDCCard GitHub source.

MDCCard can be used like a regular UIView. This is an example of a regular card:

single basic card

Swift

let card = MDCCard(frame: CGRect(x: 30, y: 100, width: 150, height: 150))
card.applyTheme(withScheme: containerScheme)
view.addSubview(card)

Objective-C

MDCCard *card = [[MDCCard alloc] initWithFrame:CGRectMake(30, 100, 150, 150)];
[card applyThemeWithScheme:containerScheme];
[view addSubview:card];

MDCCardCollectionCell example

MDCCardCollectionCell GitHub source

MDCCardCollectionCell can be used like a regular UICollectionViewCell. This is an example of MDCCardCollectionCells in a collection:

card collection cells

Swift

collectionView.register(MDCCardCollectionCell.self, forCellWithReuseIdentifier: "Cell")

func collectionView(_ collectionView: UICollectionView,
                    cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell",
                                                for: indexPath) as! MDCCardCollectionCell
  // If you wanted to have the card show the selected state when tapped
  // then you need to turn isSelectable to true, otherwise the default is false.
  cell.isSelectable = true
  cell.cornerRadius = 8
  return cell
}

Objective-C

[self.collectionView registerClass:[MDCCardCollectionCell class]
        forCellWithReuseIdentifier:@"Cell"];

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
                  cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  MDCCardCollectionCell *cell =
  [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell"
                                            forIndexPath:indexPath];
  // If you wanted to have the card show the selected state when tapped
  // then you need to turn selectable to true, otherwise the default is false.
  [cell setSelectable:YES];
  [cell setCornerRadius:8];
  return cell;
}

Anatomy and key properties

A card has a container and an optional thumbnail, header text, secondary text, media, supporting text, buttons and icons.

card anatomy diagram

  1. Container
  2. Thumbnail
  3. Header text
  4. Secondary text
  5. Media
  6. Supporting text
  7. Buttons
  8. Icons
  9. Checked icon (not shown)

Note: All the optional elements of a card's content are implemented through the use of other views/components.

MDCCard attributes

  Attribute Related method(s) Default value
Color backgroundColor -setBackgroundColor:
backgroundColor:
Surface color
Foreground color N/A N/A N/A
Stroke color layer.borderColor -setBorderColor:forState:
-borderColorForState:
On surface color at 37% opacity
Stroke width layer.borderWidth -setBorderWidth:forState:
-borderWidthForState:
1
Shape shapeGenerator -setShapeGenerator:
-shapeGenerator
MDCRectangleShapeGenerator
Elevation N/A -setShadowElevation:forState:
-shadowElevationForState:
1
Ripple color rippleView.rippleColor N/A nil

MDCCardCollectionCell attributes

  Attribute Related method(s) Default value
Color backgroundColor -setBackgroundColor:
backgroundColor:
Surface color
Foreground color N/A N/A N/A
Stroke color layer.borderColor -setBorderColor:forState:
-borderColorForState:
On surface color at 37% opacity
Stroke width layer.borderWidth -setBorderWidth:forState:
-borderWidthForState:
1
Shape shapeGenerator -setShapeGenerator:
-shapeGenerator
MDCRectangleShapeGenerator
Elevation N/A -setShadowElevation:forState:
-shadowElevationForState:
1
Ripple color rippleView.rippleColor N/A nil

Theming

Cards supports Material Theming using a Container Scheme. MDCCard and MDCCardCollectionCell have both default and outlined theming methods. Learn more about theming extensions here. Below is a screenshot of an MDCCard with the Material Design Shrine theme:

Shrine card

To make use of Cards theming install the Cards theming extensions with Cocoapods. First, add the following line to your Podfile:

pod MaterialComponents/Cards+Theming

Then run the installer:

pod install

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

Swift

import MaterialComponents.MaterialCards
import MaterialComponents.MaterialCards_Theming

...
 // Create a card
let card = MDCCard()
 // Create or use your app's Container Scheme
let containerScheme = MDCContainerScheme()
 // Theme the card with either default theme
card.applyTheme(withScheme: containerScheme)
 // Or outlined theme
card.applyOutlinedTheme(withScheme: containerScheme)

Objective-C

#import "MaterialCards.h"
#import "MaterialCards+Theming.h"

...
 // Create a card
MDCCard *card = [[MDCCard alloc] init];
 // Create or use your app's Container Scheme
MDCContainerScheme *containerScheme = [[MDCContainerScheme alloc] init];
 // Theme the card with either default theme
[self.card applyThemeWithScheme:containerScheme];
 // Or outlined theme
[self.card applyOutlinedThemeWithScheme:containerScheme];