如何在 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,只需要允许,使用UICollectionViewDelegateshouldSelectItemAt功能。

但是对于你的情况,我们需要激活多个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)
    }
}

现在我们可以同时触摸单元格了。