mirror of
https://github.com/material-components/material-components-ios.git
synced 2026-02-20 08:27:32 +08:00
169 lines
6.4 KiB
Swift
169 lines
6.4 KiB
Swift
// 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)'
|
|
]
|
|
}
|
|
}
|