Skip to content

Commit

Permalink
[Dialogs] Add title icon examples
Browse files Browse the repository at this point in the history
Adding examples for the titleIcon APIs.

PiperOrigin-RevId: 319077424
  • Loading branch information
galiak11 authored and material-automation committed Jun 30, 2020
1 parent 6f1b595 commit d220234
Show file tree
Hide file tree
Showing 5 changed files with 343 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,301 @@
// Copyright 2020-present the Material Components for iOS authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import UIKit
import MaterialComponents.MaterialCollections
import MaterialComponents.MaterialDialogs
import MaterialComponents.MaterialDialogs_Theming
import MaterialComponents.MaterialTextControls_FilledTextFields
import MaterialComponents.MaterialTextControls_FilledTextFieldsTheming
import MaterialComponents.MaterialContainerScheme
import MaterialComponents.MaterialTypographyScheme

class DialogsTitleImageExampleViewController: MDCCollectionViewController {

@objc lazy var containerScheme: MDCContainerScheming = {
let scheme = MDCContainerScheme()
scheme.colorScheme = MDCSemanticColorScheme(defaults: .material201907)
scheme.typographyScheme = MDCTypographyScheme(defaults: .material201902)
return scheme
}()

let kReusableIdentifierItem = "customCell"

var menu: [String] = []

var handler: MDCActionHandler = { action in
print(action.title ?? "Some Action")
}

override func viewDidLoad() {
super.viewDidLoad()

view.backgroundColor = containerScheme.colorScheme.backgroundColor

loadCollectionView(menu: [
"Title Icon",
"Custom Title Icon",
"Title Image - Scaled Down to Fit",
"Title Image - Bleeding Edge",
"Custom Title View",
])
}

func loadCollectionView(menu: [String]) {
self.collectionView?.register(
MDCCollectionViewTextCell.self, forCellWithReuseIdentifier: kReusableIdentifierItem)
self.menu = menu
}

override func collectionView(
_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath
) {
guard let alert = alertController(for: indexPath.row) else { return }
self.present(alert, animated: true, completion: nil)
}

private func alertController(for row: Int) -> MDCAlertController? {
switch row {
case 0:
return alertWithTitleIcon()
case 1:
return alertWithCustomTitleIcon()
case 2:
return alertWithScaledToFitImage()
case 3:
return alertWithScaledBleedingImage()
case 4:
presentAlertWithCustomTitleView()
return nil
default:
print("No row is selected")
return nil
}
}

func alertWithTitleIcon() -> MDCAlertController {
let alert = createMDCAlertController(title: "Title Icon")
alert.titleIcon = image(named: "outline_lock_black_24pt")
alert.applyTheme(withScheme: self.containerScheme)
return alert
}

func alertWithCustomTitleIcon() -> MDCAlertController {
let alert = createMDCAlertController(title: "Custom Title Icon")
// Custom size.
alert.titleIcon = image(named: "baseline_alarm_on_black_48pt")
// Custom alignment.
alert.titleIconAlignment = .center
// Custom insets.
if let alertView = alert.view as? MDCAlertControllerView {
alertView.titleIconInsets.bottom = 20
}
alert.applyTheme(withScheme: self.containerScheme)
// Custom color (overriding the theme's title icon color).
alert.titleIconTintColor = .orange
return alert
}

func alertWithScaledToFitImage() -> MDCAlertController {
let alert = createMDCAlertController(title: "Scaled Title Icon")
alert.titleIcon = image(named: "STAY_AMSTERDAM")
// Justified alignment size the image to fit the top space of the dialog. Images are scaled down
// if needed, but never scaled up.
alert.titleIconAlignment = .justified
alert.applyTheme(withScheme: self.containerScheme)
return alert
}

func alertWithScaledBleedingImage() -> MDCAlertController {
let alert = createMDCAlertController(title: "Scaled to fill Title Icon")
alert.titleIcon = image(named: "STAY_AMSTERDAM-WIDE")
// Justified alignment size the image to fit the top space of the dialog.
alert.titleIconAlignment = .justified
if let alertView = alert.view as? MDCAlertControllerView {
alertView.titleIconInsets = UIEdgeInsets(top: 0, left: 0, bottom: 20, right: 0)
}
alert.applyTheme(withScheme: self.containerScheme)
return alert
}

func presentAlertWithCustomTitleView(animated: Bool = true) {
let alert = createMDCAlertController(title: "Custom Title View")

// Create a custom view with a centered image and a light background.
let view = UIView(frame: CGRect(x: 0, y: 0, width: 160, height: 86))
let alarmView = UIImageView()
view.addSubview(alarmView)

// Apply theme colors.
view.backgroundColor = containerScheme.colorScheme.primaryColor.withAlphaComponent(0.2)
alarmView.tintColor = containerScheme.colorScheme.primaryColor

// Resize the imageView to fit to the size of the new loaded image.
if let alarm = image(named: "baseline_alarm_on_black_48pt") {
alarmView.image = alarm
alarmView.sizeToFit()
}

// Sets the customView as the titleIconView.
alert.titleIconView = view

// Set .justified alignment with 0 insets to ensure the view's color bleeds through to the edge.
alert.titleIconAlignment = .justified
if let alertView = alert.view as? MDCAlertControllerView {
alertView.titleIconInsets = UIEdgeInsets(top: 0, left: 0, bottom: 20, right: 0)
}

alert.applyTheme(withScheme: self.containerScheme)

if animated {
alarmView.alpha = 0
}
self.present(
alert, animated: animated,
completion: {
// The view is centered correctly after the alert is presented.
alarmView.center = view.center
if animated {
// Start the image animation after the alert is presetned.
alarmView.animateIn()
}
})
}

private func image(named: String) -> UIImage? {
let bundle = Bundle(for: DialogsTitleImageExampleViewController.self)
return UIImage(named: named, in: bundle, compatibleWith: nil)
}

private func createMDCAlertController(title: String?) -> MDCAlertController {
let alert = MDCAlertController(
title: title,
message: """
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
""")
alert.addAction(MDCAlertAction(title: "OK", emphasis: .high, handler: handler))
alert.addAction(MDCAlertAction(title: "Cancel", handler: handler))

// Enable dynamic type.
alert.mdc_adjustsFontForContentSizeCategory = true

return alert
}
}

// MDCCollectionViewController Data Source
extension DialogsTitleImageExampleViewController {

override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}

override func collectionView(
_ collectionView: UICollectionView, numberOfItemsInSection section: Int
) -> Int {
return menu.count
}

override func collectionView(
_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath
) -> UICollectionViewCell {

let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: kReusableIdentifierItem,
for: indexPath)
guard let customCell = cell as? MDCCollectionViewTextCell else { return cell }

customCell.isAccessibilityElement = true
customCell.accessibilityTraits = .button

let cellTitle = menu[indexPath.row]
customCell.accessibilityLabel = cellTitle
customCell.textLabel?.text = cellTitle

return customCell
}
}

// MARK: Catalog by convention
extension DialogsTitleImageExampleViewController {

@objc class func catalogMetadata() -> [String: Any] {
return [
"breadcrumbs": ["Dialogs", "Title Icon, Image & View"],
"primaryDemo": false,
"presentable": true,
]
}
}

// MARK: Snapshot Testing by Convention
extension DialogsTitleImageExampleViewController {

func resetTests() {
if presentedViewController != nil {
dismiss(animated: false)
}
}

@objc func testTitleIcon() {
resetTests()
self.present(
alertWithTitleIcon(), animated: false, completion: nil)
}

@objc func testCustomTitleIcon() {
resetTests()
self.present(
alertWithCustomTitleIcon(), animated: false, completion: nil)
}

@objc func testScaledToFit() {
resetTests()
self.present(
alertWithScaledToFitImage(), animated: false, completion: nil)
}

@objc func testScaledBleeding() {
resetTests()
self.present(
alertWithScaledBleedingImage(), animated: false, completion: nil)
}

@objc func testCustomTitleView() {
resetTests()
presentAlertWithCustomTitleView(animated: false)
}
}

extension UIView {
fileprivate func animateIn(
duration: TimeInterval = 2, options: UIView.AnimationOptions = [.curveEaseOut]
) {
alpha = 0.2
self.transform = self.transform
.translatedBy(x: -self.frame.origin.x / 2, y: 0)
.scaledBy(x: 0.2, y: 0.2)
.rotated(by: CGFloat.pi)
UIView.animate(
withDuration: duration,
delay: 0,
usingSpringWithDamping: 0.3,
initialSpringVelocity: 0.3,
options: options,
animations: {
self.transform = CGAffineTransform.identity
self.alpha = 1
}, completion: nil)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "STAY_AMSTERDAM-WIDE.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "STAY_AMSTERDAM.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit d220234

Please sign in to comment.