-
Notifications
You must be signed in to change notification settings - Fork 944
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding examples for the titleIcon APIs. PiperOrigin-RevId: 319077424
- Loading branch information
1 parent
6f1b595
commit d220234
Showing
5 changed files
with
343 additions
and
0 deletions.
There are no files selected for viewing
301 changes: 301 additions & 0 deletions
301
components/Dialogs/examples/DialogsTitleImageExampleViewController.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
...logs/examples/resources/DialogsAssets.xcassets/STAY_AMSTERDAM-WIDE.imageset/Contents.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} |
Binary file added
BIN
+578 KB
...ces/DialogsAssets.xcassets/STAY_AMSTERDAM-WIDE.imageset/STAY_AMSTERDAM-WIDE.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions
21
...s/Dialogs/examples/resources/DialogsAssets.xcassets/STAY_AMSTERDAM.imageset/Contents.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} |
Binary file added
BIN
+775 KB
...les/resources/DialogsAssets.xcassets/STAY_AMSTERDAM.imageset/STAY_AMSTERDAM.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.