如何在 Swift 3 中多点触摸 UICollectionViewCell

Posted

技术标签:

【中文标题】如何在 Swift 3 中多点触摸 UICollectionViewCell【英文标题】:How to multiple touch UICollectionViewCells in Swift 3 【发布时间】:2016-10-15 17:31:09 【问题描述】:

对于当前项目,我需要能够同时触摸多个 UICollectionViewCells。 我曾尝试使用 UICollectionViewDelegate,但我无法让 Cells 能够同时被触摸。

这是我的代码:

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)



【问题讨论】:

【参考方案1】:

要“激活”多个单元格选择,您只需要允许它,使用UICollectionViewDelegateshouldSelectItemAt 函数。

但在您的情况下,我们需要激活多个 Cell 触摸。为了能够做到这一点,我现在使用了 UIGestureRecognizers:

首先我们需要为每个单元设置一个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)
    

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

【讨论】:

我现在打开Xcode,给你一个代码示例 非常感谢! 提供了代码。现在测试它,但它应该可以工作 仍在测试以提供最佳结果 在他的例子中,他不会重复使用。他有固定数量的单元格,它们始终是视图的一部分,不会滚动并滚动回视图

以上是关于如何在 Swift 3 中多点触摸 UICollectionViewCell的主要内容,如果未能解决你的问题,请参考以下文章

基于Visual C#2010开发Windows7应用 多点触摸图片处理应用程序-使用多点触摸操作处理图片

多点触摸屏——电容屏驱动程序

iOS 上 MonoTouch 中的多点触控

单点触摸屏与多点触摸屏的异同

xcode 8 swift 3 中多点连接框架中对成员“会话(_:peer:didChange)”错误的模糊引用

Linux 中的多点触控