How to receive touches on a UICollectionView in th

2019-06-15 02:33发布

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.

6条回答
该账号已被封号
2楼-- · 2019-06-15 02:54

some "cosmetics" for Swift 4.2: (thxs to other authors above.. :) )

// TOUCHES in empty space:

private func addGestureRecognizers(){
    let tapGestureRecogniser = UITapGestureRecognizer(target: self, action: #selector(handleTapEmptySpaceGesture))
    tapGestureRecogniser.delegate = self
    collectionView.addGestureRecognizer(tapGestureRecogniser)
}


@objc func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    // only handle tapping empty space (i.e. not a cell)
    let point = gestureRecognizer.location(in: collectionView)
    let indexPath = collectionView.indexPathForItem(at: point)
    return indexPath == nil
}
查看更多
该账号已被封号
3楼-- · 2019-06-15 02:58

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
}
查看更多
做自己的国王
4楼-- · 2019-06-15 02:58

This worked for me on Swift 2.3

Step 1 : Implement the UIGestureRecognizerDelegate protocol

Step 2 : Set UITapGestureRecognizer on the UICollectionView backgroundView

Step 3 : Handle what to do on tap inside handleTap function

class namScreenVcc: UICollectionViewController, UIViewControllerTransitioningDelegate, UIGestureRecognizerDelegate
{
    override func viewDidLoad()
    {
        super.viewDidLoad()

        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
        tapGestureRecognizer.delegate = self

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

    func handleTap(recognizer: UITapGestureRecognizer)
    {
        // Handle the tap gesture
    }
}
查看更多
Melony?
5楼-- · 2019-06-15 03:04

didSelectItem delegate method will be called only when the user selects collectionViewCell. The space between the cells may vary depending on the each cell Size, you can specify only min spacing. To recieve the touches keep supplementaryView as backgroundView by changing its zindex, add touch detection to it. Hope this will help you. :)

查看更多
老娘就宠你
6楼-- · 2019-06-15 03:16

Based on Paul Popiel's answer but in Objective C

To set up the gesture recognizer:

//The setup code (in viewDidLoad in your view controller)
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
                                        action:@selector(handleSingleTap:)];
[self.collectionView addGestureRecognizer:singleFingerTap];

And to handle the tap and recognize if it is touching a cell or space not covered by a cell

- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
    CGPoint location = [recognizer locationInView:[recognizer.view superview]];
    NSIndexPath* indexPath = [self.collectionView indexPathForItemAtPoint:location];
    if (!indexPath)
    {
        //Handle your selection of the white space in the collection view here.  Your code may vary.
        [self setSelected:YES];
    } else {
        //Handle selection of individual cell here
        [self collectionView:self.collectionView didSelectItemAtIndexPath:indexPath];
    }
}
查看更多
放荡不羁爱自由
7楼-- · 2019-06-15 03:18

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.

查看更多
登录 后发表回答