material-components_materia.../components/Ripple/examples/UICollectionViewWithRippleExample.swift
Yarden Eitan a68702e3a4 [Ripple] Add delegate method to RippleTouchController existing in InkTouchController.
This delegate method allows clients to have one ripple touch controller control multiple ripple views. Also gives them more flexibility on the creation and reusing of ripple views.

PiperOrigin-RevId: 317614179
2020-06-22 02:18:07 -07:00

190 lines
5.7 KiB
Swift

// 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.MaterialRipple
import MaterialComponents.MaterialContainerScheme
class RippleCell: UICollectionViewCell {
var rippleView: MDCRippleView!
override init(frame: CGRect) {
super.init(frame: frame)
rippleView = MDCRippleView(frame: self.contentView.bounds)
self.contentView.addSubview(rippleView)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class UICollectionViewWithRippleExample: UIViewController,
UICollectionViewDelegate,
UICollectionViewDataSource,
UICollectionViewDelegateFlowLayout,
MDCRippleTouchControllerDelegate
{
let collectionView = UICollectionView(
frame: .zero,
collectionViewLayout: UICollectionViewFlowLayout())
var rippleTouchController: MDCRippleTouchController?
@objc var containerScheme: MDCContainerScheming!
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
containerScheme = MDCContainerScheme()
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = containerScheme.colorScheme.backgroundColor
collectionView.backgroundColor = containerScheme.colorScheme.backgroundColor
collectionView.frame = view.bounds
collectionView.dataSource = self
collectionView.delegate = self
collectionView.backgroundColor = .white
collectionView.alwaysBounceVertical = true
collectionView.register(RippleCell.self, forCellWithReuseIdentifier: "Cell")
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.allowsMultipleSelection = true
view.addSubview(collectionView)
rippleTouchController = MDCRippleTouchController(view: collectionView)
rippleTouchController?.delegate = self
if #available(iOS 11, *) {
let guide = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
collectionView.leftAnchor.constraint(equalTo: guide.leftAnchor),
collectionView.rightAnchor.constraint(equalTo: guide.rightAnchor),
collectionView.topAnchor.constraint(equalTo: view.topAnchor),
collectionView.bottomAnchor.constraint(equalTo: guide.bottomAnchor),
])
collectionView.contentInsetAdjustmentBehavior = .always
} else {
preiOS11Constraints()
}
}
func preiOS11Constraints() {
self.view.addConstraints(
NSLayoutConstraint.constraints(
withVisualFormat: "H:|[view]|",
options: [],
metrics: nil,
views: ["view": collectionView]))
self.view.addConstraints(
NSLayoutConstraint.constraints(
withVisualFormat: "V:|[view]|",
options: [],
metrics: nil,
views: ["view": collectionView]))
}
func collectionView(
_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath
) -> UICollectionViewCell {
guard
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
as? RippleCell
else { fatalError() }
cell.layer.borderWidth = 1
cell.layer.borderColor = UIColor.lightGray.cgColor
cell.backgroundColor = containerScheme.colorScheme.surfaceColor
return cell
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(
_ collectionView: UICollectionView,
numberOfItemsInSection section: Int
) -> Int {
return 30
}
func collectionView(
_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath
) -> CGSize {
let size = collectionView.bounds.size.width - 12
return CGSize(width: size, height: 60)
}
func collectionView(
_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAt section: Int
) -> UIEdgeInsets {
return UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
}
func collectionView(
_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAt section: Int
) -> CGFloat {
return 8
}
func collectionView(
_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumInteritemSpacingForSectionAt section: Int
) -> CGFloat {
return 8
}
func rippleTouchController(
_ rippleTouchController: MDCRippleTouchController,
rippleViewAtTouchLocation location: CGPoint
) -> MDCRippleView? {
guard let indexPath = self.collectionView.indexPathForItem(at: location) else {
return nil
}
let cell = self.collectionView.cellForItem(at: indexPath) as? RippleCell
if let cell = cell {
return cell.rippleView
}
return nil
}
}
extension UICollectionViewWithRippleExample {
@objc class func catalogMetadata() -> [String: Any] {
return [
"breadcrumbs": ["Ripple", "UICollectionView with Ripple"],
"primaryDemo": false,
"presentable": false,
]
}
}