Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to receive touches on a UICollectionView in the blank space around all cells

I have a UICollectionView that has different items in it. When I tap on an item, I use:

 -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

to figure out what was touched and then basically set the alpha of that view to 0 to hide it. That all works fine. Now what I would like to do is when you tap on the white space surrounding all of the UICollectionViewCells all of the views then appear again. I am having trouble finding a method that will allow me to know when the white space around the cells has been touched. Is there a good way to do that? I have tried setting up a gesture recognizer, but when I do that, my method

 -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

isn't called. Is there some way to to just implement the gesture recognizer and from there determine if a cell was tapped and if so hide that cell, else show all the hidden cells? Thanks.

like image 658
Blane Townsend Avatar asked Jul 11 '14 16:07

Blane Townsend


People also ask

How does UICollectionView work?

The collection view presents items onscreen using a cell, which is an instance of the UICollectionViewCell class that your data source configures and provides. In addition to its cells, a collection view can present data using other types of views.

How is UICollectionView implemented?

Create a new iOS app project Add a CollectionView by pressing command shift L to open the storyboard widget window. Drag the collectionView onto the main view controller. Add constraints to the UICollectionView widget to ensure that the widget fills the screen on all devices.


2 Answers

I ran into a similar scenario in my project and solved it by doing the following:

let tapGestureRecogniser = UITapGestureRecognizer(target: self, action: #selector(handleTapEmptySpaceGesture))
tapGestureRecogniser.delegate = self
collectionView.addGestureRecognizer(tapGestureRecogniser)

Implement the UIGestureRecognizerDelegate protocol

Then implement the following function in the protocol:

func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
    // only handle tapping empty space (i.e. not a cell)
    let point = gestureRecognizer.locationInView(collectionView)
    let indexPath = collectionView.indexPathForItemAtPoint(point)
    return indexPath == nil
}

Basically if the click is on a cell then your gesture recognizer doesn't begin, allowing the normal selection/deselect delegates to run. Otherwise if it's on empty space your recogniser handles the tap and runs its handler.

like image 22
Paul Popiel Avatar answered Oct 01 '22 03:10

Paul Popiel


I've managed to fix this problem by using a UITapGestureRecognizer on the UICollectionView backgroundView. It's in Swift, but the idea is clear:

self.tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "handleTap:")
self.tapGestureRecognizer.delegate = self

self.collectionView.backgroundView = UIView(frame:self.collectionView.bounds)
self.collectionView.backgroundView!.addGestureRecognizer(tapGestureRecognizer)

And the callback:

func handleTap(recognizer: UITapGestureRecognizer) {
    // Handle the tap gesture
}
like image 79
Antoine Avatar answered Oct 01 '22 03:10

Antoine