如何在 Swift 3 中多次触摸 UICollectionViewCells
How to multiple touch UICollectionViewCells in Swift 3
对于当前的项目,我需要能够同时触摸多个 UICollectionViewCells。
我曾尝试使用 UICollectionViewDelegate,但我无法让 Cell 能够同时被触摸。
这是我的代码:
import UIKit
private let reuseIdentifier = "CustomCell"
class CollectionViewController: UICollectionViewController {
let sectionInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
let numOfPads = 24
let numOfColumns = 4
func initConfig(){
collectionView?.backgroundColor = UIColor.white
//
collectionView?.indicatorStyle = UIScrollViewIndicatorStyle.white
//
//collectionView?.backgroundView = UIView(frame: (collectionView?.frame)!)
// lets iOS recover and respond to more than one finger touch at a time
collectionView?.isMultipleTouchEnabled = true
collectionView?.allowsSelection = true
collectionView?.allowsMultipleSelection = true
collectionView?.isUserInteractionEnabled = true
// This makes tapping on the UICollectionViewCell feel zippy
collectionView?.delaysContentTouches = false
// Kill any kind of scrolling
collectionView?.isScrollEnabled = false
}
func generateRandomColor() -> UIColor {
let redValue = CGFloat(arc4random() % 255) / 255.0
let blueValue = CGFloat(arc4random() % 255) / 255.0
let greenValue = CGFloat(arc4random() % 255) / 255.0
return UIColor(red: redValue, green: greenValue, blue: blueValue, alpha: 0.5)
}
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Register cell classes
self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
// Do any additional setup after loading the view.
initConfig()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: UICollectionViewDataSource
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 24
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
cell.backgroundColor = generateRandomColor()
return cell
}
// MARK: UICollectionViewDelegate
override func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
if let selectedItems = collectionView.indexPathsForSelectedItems {
if selectedItems.contains(indexPath as IndexPath) {
collectionView.deselectItem(at: indexPath as IndexPath, animated: true)
return false
}
}
return true
}
override func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
print("didHighlightItemAt", indexPath)
let cell = collectionView.cellForItem(at: indexPath)! as UICollectionViewCell
cell.contentView.backgroundColor = UIColor.white
}
override func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) {
//print("didUnhighlightItemAt", indexPath)
let cell = collectionView.cellForItem(at: indexPath)! as UICollectionViewCell
cell.contentView.backgroundColor = UIColor.clear
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("didSelectItemAt", selectedCells)
}
}
要"activate"多选Cell,只需要允许,使用UICollectionViewDelegate
的shouldSelectItemAt
功能。
但是对于你的情况,我们需要激活多个Cell touch。为了能够做到这一点,我现在使用了 UIGestureRecognizers:
首先我们需要为每个 Cell 设置一个 GestureRecognizer
:
extension ViewController: UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath)
let lpgr = UITapGestureRecognizer(target: self, action: #selector(tap(gestureReconizer:)))
lpgr.delegate = self
cell.addGestureRecognizer(lpgr)
return cell
}
}
然后我们需要接收被点击的Cell:
extension ViewController: UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
func tap(gestureReconizer: UITapGestureRecognizer) {
let tapLocation = gestureReconizer.location(in: self.collectionView)
//using the tapLocation to get the indexPath
let indexPath = self.collectionView.indexPathForItem(at: tapLocation)
//now we can get the cell for item at indexPath
let cell = self.collectionView.cellForItem(at: indexPath!)
cell?.backgroundColor = generateRandomColor()
doWhatEver(cell: cell!)
}
func doWhatEver(cell: UICollectionViewCell) {
//here we do whatever like play the desired sounds of the cells.
}
//or we just use your random color function for fun
func generateRandomColor() -> UIColor {
let redValue = CGFloat(arc4random() % 255) / 255.0
let blueValue = CGFloat(arc4random() % 255) / 255.0
let greenValue = CGFloat(arc4random() % 255) / 255.0
return UIColor(red: redValue, green: greenValue, blue: blueValue, alpha: 0.5)
}
}
现在我们可以同时触摸单元格了。
对于当前的项目,我需要能够同时触摸多个 UICollectionViewCells。 我曾尝试使用 UICollectionViewDelegate,但我无法让 Cell 能够同时被触摸。
这是我的代码:
import UIKit
private let reuseIdentifier = "CustomCell"
class CollectionViewController: UICollectionViewController {
let sectionInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
let numOfPads = 24
let numOfColumns = 4
func initConfig(){
collectionView?.backgroundColor = UIColor.white
//
collectionView?.indicatorStyle = UIScrollViewIndicatorStyle.white
//
//collectionView?.backgroundView = UIView(frame: (collectionView?.frame)!)
// lets iOS recover and respond to more than one finger touch at a time
collectionView?.isMultipleTouchEnabled = true
collectionView?.allowsSelection = true
collectionView?.allowsMultipleSelection = true
collectionView?.isUserInteractionEnabled = true
// This makes tapping on the UICollectionViewCell feel zippy
collectionView?.delaysContentTouches = false
// Kill any kind of scrolling
collectionView?.isScrollEnabled = false
}
func generateRandomColor() -> UIColor {
let redValue = CGFloat(arc4random() % 255) / 255.0
let blueValue = CGFloat(arc4random() % 255) / 255.0
let greenValue = CGFloat(arc4random() % 255) / 255.0
return UIColor(red: redValue, green: greenValue, blue: blueValue, alpha: 0.5)
}
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Register cell classes
self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
// Do any additional setup after loading the view.
initConfig()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: UICollectionViewDataSource
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 24
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
cell.backgroundColor = generateRandomColor()
return cell
}
// MARK: UICollectionViewDelegate
override func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
if let selectedItems = collectionView.indexPathsForSelectedItems {
if selectedItems.contains(indexPath as IndexPath) {
collectionView.deselectItem(at: indexPath as IndexPath, animated: true)
return false
}
}
return true
}
override func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
print("didHighlightItemAt", indexPath)
let cell = collectionView.cellForItem(at: indexPath)! as UICollectionViewCell
cell.contentView.backgroundColor = UIColor.white
}
override func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) {
//print("didUnhighlightItemAt", indexPath)
let cell = collectionView.cellForItem(at: indexPath)! as UICollectionViewCell
cell.contentView.backgroundColor = UIColor.clear
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("didSelectItemAt", selectedCells)
}
}
要"activate"多选Cell,只需要允许,使用UICollectionViewDelegate
的shouldSelectItemAt
功能。
但是对于你的情况,我们需要激活多个Cell touch。为了能够做到这一点,我现在使用了 UIGestureRecognizers:
首先我们需要为每个 Cell 设置一个 GestureRecognizer
:
extension ViewController: UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath)
let lpgr = UITapGestureRecognizer(target: self, action: #selector(tap(gestureReconizer:)))
lpgr.delegate = self
cell.addGestureRecognizer(lpgr)
return cell
}
}
然后我们需要接收被点击的Cell:
extension ViewController: UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
func tap(gestureReconizer: UITapGestureRecognizer) {
let tapLocation = gestureReconizer.location(in: self.collectionView)
//using the tapLocation to get the indexPath
let indexPath = self.collectionView.indexPathForItem(at: tapLocation)
//now we can get the cell for item at indexPath
let cell = self.collectionView.cellForItem(at: indexPath!)
cell?.backgroundColor = generateRandomColor()
doWhatEver(cell: cell!)
}
func doWhatEver(cell: UICollectionViewCell) {
//here we do whatever like play the desired sounds of the cells.
}
//or we just use your random color function for fun
func generateRandomColor() -> UIColor {
let redValue = CGFloat(arc4random() % 255) / 255.0
let blueValue = CGFloat(arc4random() % 255) / 255.0
let greenValue = CGFloat(arc4random() % 255) / 255.0
return UIColor(red: redValue, green: greenValue, blue: blueValue, alpha: 0.5)
}
}
现在我们可以同时触摸单元格了。