iosswiftuicollectionviewtouchesbeganuicollectionviewdelegate

touchesBegan not firing in UICollectionViewController


I have a UICollectionViewController class that lays out bunch of cells. When the user touches a cell, I want to use the touchesBegan method to prevent new touches until the first touch has completed its selection of a cell.

I tried putting the following code in my view controller but it never gets called.

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    super.touchesBegan(touches, withEvent: event)
    print("touches began")
}

However, elsewhere in my project I have another class that's a subclass of UIViewController. There, I use touchesBegan in the following code to dismiss the keyboard for a text view in that class, and that code gets called just fine.

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    super.touchesBegan(touches, withEvent: event)
    view.endEditing(true)
}

Why does this code work in one class and not the other? And how can I use touchesBegan in my UICollectionViewController to detect touches on my collection view cells? Solutions in Swift would be appreciated. Thanks for your time!

Research: I checked out this solution: Handle Touch in UiCollectionView? But the answers mostly apply to that specific project.

I tried using a gesture recognizer to run self.collectionView?.userInteractionEnabled = false but the gesture recognizer does not fire for selector.state == .Began, only for .Ended. So I could not use it to prevent further touches.

I also tried using a UILongPressGestureRecognizer to do the same thing, but that gesture prevents the default tap gesture which the collection view cells listen for, so the regular tap on the cells was never received and thus the cells cannot be selected.

I posted a workaround as an answer, although it does not answer the original question.


Solution

  • This is sort of a workaround but instead of using touchesBegan I used the UICollectionViewDelegate protocol and this works for letting me select a cell in UICollectionView.

    // The specified item should be selected.
    override func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
        return true
    }
    
    override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        colorIndex = (indexPath as NSIndexPath).item // sets color index to the selected cell's path
        let selectedCell = collectionView.cellForItem(at: indexPath) as UICollectionViewCell!
    print("Cell selected: \(selectedCell)")