blob: 0004bc30e74689cc8e0b5d2173eba71a916a0ed4 [file] [log] [blame]
// Copyright 2019-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.MaterialContainerScheme
private let reuseIdentifier = "Cell"
/// This example uses a custom toggle button in Cards. It uses a custom class (ToggleButtonCell),
/// which is a subclass of MDCCardCollectionCell (a UICollectionCell subclass). ToggleButtonCell
/// sets the card's image, its selected and unselecte icons, and the tint color of the selected and
/// unselected icon. This ToggleButtonCollectionViewController class customizes the collection cells
/// and enables the toggle button in [collectionView:cellForItemAt:].
class ToggleButtonCollectionViewController: UICollectionViewController,
UICollectionViewDelegateFlowLayout
{
fileprivate let layout = UICollectionViewFlowLayout()
@objc var containerScheme: MDCContainerScheming
let padding: CGFloat = 8
var dataSource = [
(image: "toggle-button-image1", accessibilityLabel: "Teapot", selected: false),
(image: "toggle-button-image4", accessibilityLabel: "Vases", selected: true),
(image: "toggle-button-image3", accessibilityLabel: "Tape", selected: true),
(image: "toggle-button-image2", accessibilityLabel: "Cup", selected: false),
(image: "toggle-button-image1", accessibilityLabel: "Teapot", selected: false),
(image: "toggle-button-image4", accessibilityLabel: "Vases", selected: false),
(image: "toggle-button-image3", accessibilityLabel: "Tape", selected: false),
(image: "toggle-button-image2", accessibilityLabel: "Cup", selected: false),
]
init() {
let layout = UICollectionViewFlowLayout()
layout.minimumLineSpacing = padding
layout.minimumInteritemSpacing = padding
layout.sectionInset = UIEdgeInsets(top: padding, left: padding, bottom: padding, right: padding)
containerScheme = MDCContainerScheme()
super.init(collectionViewLayout: layout)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView.register(
ToggleButtonCell.self, forCellWithReuseIdentifier: String(describing: ToggleButtonCell.self))
collectionView.allowsMultipleSelection = true
collectionView.backgroundColor = containerScheme.colorScheme.surfaceColor
self.title = "Cards Toggle Button"
}
override func viewWillTransition(
to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator
) {
super.viewWillTransition(to: size, with: coordinator)
// Recalculate cell size when orientation changes
collectionView.collectionViewLayout.invalidateLayout()
}
}
// MARK: UICollectionViewDataSource
extension ToggleButtonCollectionViewController {
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(
_ collectionView: UICollectionView, numberOfItemsInSection section: Int
) -> Int {
return dataSource.count
}
override func collectionView(
_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath
) -> UICollectionViewCell {
// Get our custom cell, which is a card cell subclass, with a custom toggle icon.
let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: String(describing: ToggleButtonCell.self), for: indexPath)
guard let cardCell = cell as? ToggleButtonCell else { return cell }
// Get the card cell's data from the data source.
let imagedata = dataSource[indexPath.item]
// Set the card's image based on the datasource.
cardCell.setCardImage(named: imagedata.image)
// Apply the Material theme to the cards, which uses the primary color to theme the toggle
// button color. In this example, we've overriden it with a white color.
cardCell.applyTheme(withScheme: containerScheme)
cardCell.setImageTintColor(.white, for: .normal) // Override the default toggle color.
// Enable toggle button behavior in the card.
cardCell.isSelectable = true
// Select the card based on its state in the data source.
cardCell.isSelected = imagedata.selected
if imagedata.selected {
collectionView.selectItem(at: indexPath, animated: true, scrollPosition: [])
}
// Ensure the card is accessible.
cardCell.isAccessibilityElement = true
cardCell.accessibilityLabel = imagedata.accessibilityLabel
return cardCell
}
}
// MARK: UICollectionViewDelegate
extension ToggleButtonCollectionViewController {
override func collectionView(
_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath
) {
dataSource[indexPath.item].selected = true
}
override func collectionView(
_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath
) {
dataSource[indexPath.item].selected = false
}
func collectionView(
_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath
) -> CGSize {
let cardWidth = (collectionView.bounds.size.width - padding * 3) / 2
return CGSize(width: cardWidth, height: cardWidth)
}
}
// MARK: Catalog By convention
extension ToggleButtonCollectionViewController {
@objc class func catalogMetadata() -> [String: Any] {
return [
"breadcrumbs": ["Cards", "Toggle Button in Cards"],
"primaryDemo": false,
"presentable": true,
"skip_snapshots": true, // Crashing on iPhone 5S iOS 10.3 with 'Unable to install constraint on view. Does the constraint reference something from outside the subtree of the view? That's illegal. constraint:<NSLayoutConstraint:0x610000887350 H:|-(0)-[UIView:0x7ffa93c3a220] (active, names: '|':ToggleButtonCell:0x7ffa93c39d60 )> view:<UIImageView: 0x7ffa93e40210; frame = (0 0; 0 0); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x61000003ec00>> - (null)'
]
}
}