可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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 UICollectionViewCell
s 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.
回答1:
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
}
回答2:
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.
回答3:
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. :)
回答4:
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
}
}
回答5:
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
}
回答6:
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];
}
}