| // 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 DialogsAlignmentExampleViewController: 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: [ | |
| "Centered", | |
| "Justified Action", | |
| "Justified Actions", | |
| "Vertical Justified Actions", | |
| "Vertical Actions In Reversed Order", | |
| "Custom Insets", | |
| ]) | |
| } | |
| 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 alertWithCenteredContent() | |
| case 1: | |
| return alertWithJustifiedAction() | |
| case 2: | |
| return alertWithJustifiedActions() | |
| case 3: | |
| return alertWithVerticallyJustifiedActions() | |
| case 4: | |
| return alertWithVerticalActionsInReverseOrder() | |
| case 5: | |
| return alertWithCustomInsets() | |
| default: | |
| print("No row is selected") | |
| return nil | |
| } | |
| } | |
| func alertWithCenteredContent() -> MDCAlertController { | |
| let alert = createMDCAlertController(title: "Centered Title") | |
| let bundle = Bundle(for: DialogsAlignmentExampleViewController.self) | |
| alert.titleIcon = UIImage(named: "outline_lock_black_24pt", in: bundle, compatibleWith: nil) | |
| alert.titleAlignment = .center | |
| alert.titleIconAlignment = .center | |
| alert.messageAlignment = .center | |
| alert.actionsHorizontalAlignment = .center | |
| alert.applyTheme(withScheme: containerScheme) | |
| return alert | |
| } | |
| func alertWithJustifiedAction() -> MDCAlertController { | |
| let alert = MDCAlertController( | |
| title: "Justified Action", message: "Lorem ipsum dolor sit amet, consectetur adipiscing elit." | |
| ) | |
| alert.addAction(MDCAlertAction(title: "Got It", emphasis: .high, handler: handler)) | |
| alert.actionsHorizontalAlignment = .justified | |
| alert.applyTheme(withScheme: containerScheme) | |
| return alert | |
| } | |
| func alertWithJustifiedActions() -> MDCAlertController { | |
| let alert = createMDCAlertController(title: "Justified Actions") | |
| alert.actionsHorizontalAlignment = .justified | |
| alert.applyTheme(withScheme: containerScheme) | |
| return alert | |
| } | |
| func alertWithVerticallyJustifiedActions() -> MDCAlertController { | |
| let alert = MDCAlertController( | |
| title: "Vertical Actions", message: "Lorem ipsum dolor sit amet, consectetur adipiscing elit." | |
| ) | |
| alert.addAction(MDCAlertAction(title: "Sed do eiusmod", emphasis: .high, handler: handler)) | |
| alert.addAction(MDCAlertAction(title: "Tempor incididunt", emphasis: .medium, handler: handler)) | |
| alert.actionsHorizontalAlignmentInVerticalLayout = .justified | |
| alert.applyTheme(withScheme: containerScheme) | |
| return alert | |
| } | |
| func alertWithVerticalActionsInReverseOrder() -> MDCAlertController { | |
| let alert = MDCAlertController( | |
| title: "Reversed Vertical Order", | |
| message: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") | |
| alert.addAction(MDCAlertAction(title: "Sed do eiusmod", handler: handler)) | |
| alert.addAction(MDCAlertAction(title: "Tempor incididunt", handler: handler)) | |
| alert.actionsHorizontalAlignmentInVerticalLayout = .trailing | |
| alert.orderVerticalActionsByEmphasis = true | |
| alert.applyTheme(withScheme: containerScheme) | |
| return alert | |
| } | |
| func alertWithCustomInsets() -> MDCAlertController { | |
| let alert = MDCAlertController( | |
| title: "Custom Insets", | |
| message: """ | |
| Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. | |
| """) | |
| alert.addAction(MDCAlertAction(title: "Accept", emphasis: .medium, handler: handler)) | |
| alert.addAction(MDCAlertAction(title: "Cancel", emphasis: .medium, handler: handler)) | |
| alert.actionsHorizontalAlignment = .justified | |
| if let alertView = alert.view as? MDCAlertControllerView { | |
| alertView.titleInsets = UIEdgeInsets(top: 30, left: 30, bottom: 20, right: 30) | |
| alertView.contentInsets = UIEdgeInsets(top: 0, left: 30, bottom: 20, right: 30) | |
| alertView.actionsInsets = UIEdgeInsets(top: 8, left: 30, bottom: 30, right: 30) | |
| alertView.actionsHorizontalMargin = 16 | |
| } | |
| alert.applyTheme(withScheme: containerScheme) | |
| return alert | |
| } | |
| private func createMDCAlertController(title: String?) -> MDCAlertController { | |
| let alertController = MDCAlertController( | |
| title: title, | |
| message: """ | |
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. | |
| """) | |
| alertController.addAction(MDCAlertAction(title: "OK", emphasis: .high, handler: handler)) | |
| alertController.addAction(MDCAlertAction(title: "Cancel", emphasis: .medium, handler: handler)) | |
| return alertController | |
| } | |
| } | |
| // MDCCollectionViewController Data Source | |
| extension DialogsAlignmentExampleViewController { | |
| 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 DialogsAlignmentExampleViewController { | |
| @objc class func catalogMetadata() -> [String: Any] { | |
| return [ | |
| "breadcrumbs": ["Dialogs", "Alignment and Insets"], | |
| "primaryDemo": false, | |
| "presentable": true, | |
| ] | |
| } | |
| } | |
| // MARK: Snapshot Testing by Convention | |
| extension DialogsAlignmentExampleViewController { | |
| func resetTests() { | |
| if presentedViewController != nil { | |
| dismiss(animated: false) | |
| } | |
| } | |
| @objc func testCentered() { | |
| resetTests() | |
| self.present(alertWithCenteredContent(), animated: false, completion: nil) | |
| } | |
| @objc func testJustifiedAction() { | |
| resetTests() | |
| self.present(alertWithJustifiedAction(), animated: false, completion: nil) | |
| } | |
| @objc func testJustifiedActions() { | |
| resetTests() | |
| self.present(alertWithJustifiedActions(), animated: false, completion: nil) | |
| } | |
| @objc func testVerticalJustified() { | |
| resetTests() | |
| self.present(alertWithVerticallyJustifiedActions(), animated: false, completion: nil) | |
| } | |
| @objc func testReverseVerticalOrder() { | |
| resetTests() | |
| self.present(alertWithVerticalActionsInReverseOrder(), animated: false, completion: nil) | |
| } | |
| @objc func testCustomInsets() { | |
| resetTests() | |
| self.present(alertWithCustomInsets(), animated: false, completion: nil) | |
| } | |
| } |