I have a table view with a pan gesture on it. When I start panning the tableview up and down the tableView selection gets disable and I can't select tableview cells.
UIPanGesture* tablePanGesture =[[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(gestureHandler:)];
tablePanGesture.delegate = self;
[tableView addGestureRecognizer:tablePanGesture];
[tablePanGesture setCancelsTouchesInView:NO];
And I using the following delegate to let my gestures and tableview gestures work together:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
I have implemented the method for table view didSelectRowAtIndexPath but when I use panning it is not called.
Is there any conflict between pan gesture and tableview Delegate?
You are missing this line:-
[tablePanGesture setCancelsTouchesInView:NO];
This will let the UIPanGesture recognize the pan gesture and also pass the touch to the next responder means your table view select or tap.
Related
I have a ViewController with a vertically scrolling collection view that takes up the entire view. I want to be able to get swipe and pan gestures on the entire collection view (not just on cells) but I can't get any gestures. I have tried adding the gesture recognizer to the view and the collection view but neither seem to work.
Adding the gesture recognizer to the view
self.panEdgeGesture = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
self.panEdgeGesture.delegate = self;
[self.collectionView addGestureRecognizer:self.panEdgeGesture];
[self.panEdgeGesture setEdges:UIRectEdgeRight];
Then I added these functions:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch{
return YES;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
- (void)handlePan:(UISwipeGestureRecognizer *)sender
{
DebugLog(#"Received pan gesture");
}
Could the collection view cells stop the gesture events from triggering? They have no gestures themselves.
Per UIScreenEdgePanGestureRecognizer's Class Reference:
After creating a screen edge pan gesture recognizer, assign an
appropriate value to the edges property before attaching the gesture
recognizer to your view. You use this property to specify from which
edges the gesture may start. This gesture recognizer ignores any
touches beyond the first touch.
So change you code to:
self.panEdgeGesture = [[UIScreenEdgePanGestureRecognizer alloc];
[self.panEdgeGesture setEdges:UIRectEdgeRight];
initWithTarget:self action:#selector(handlePan:)];
self.panEdgeGesture.delegate = self;
[self.collectionView addGestureRecognizer:self.panEdgeGesture];
I'm having trouble adding a long press gesture to my UITableView. Well, technically, I do have a long press gesture recognizer, but I set the minimum taps duration to 0.08. I did this because I want to have the same general action for tapping and holding down a cell, but the action only changes based on how long the cell was held. Anyway, here is the code where I add the gesture recognizer (in viewDidLoad) :
var longPress:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: "handleLongPress:")
longPress.minimumPressDuration = 0.08
longPress.delegate = self
longPress.cancelsTouchesInView = false
self.tableView.addGestureRecognizer(longPress)
self.tableView.panGestureRecognizer.requireGestureRecognizerToFail(longPress)
In my handleLongPress() function, I get the CGPoint where there was a long press and then get the tableView cell from that.
So basically, if I scroll quickly, (like if I flick the screen), the table view scrolls fine. If I try to scroll slowly, the long press event fires and I can't scroll.
All I want to do is to be able to scroll slowly, I want the tableviews default scroll gesture to override any long press.
Thanks!
ScrollViews have a panGestureRecognizer property, you can call requireGestureRecognizerToFail on your long press recognizer with the scrollView's panGestureRecognizer as an argument and it will only fire if the pan gesture in the scroll view fails.
This category might solve your problem:
#interface UITableView (CellSwipeAdditions)
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
#end
#implementation UITableView (CellSwipeAdditions)
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
#end
I setup a UITapGestureRecognizer on a UIScrollView in the storyboard. The Scroll View contains other contents (two UIView, one UIWebView).
The Gesture Recognizer properties are as follows:
Action: dismissPopover
delegate: postViewController
gestureRecognizers: Scroll View
state: enabled
numberOfTapsRequired: 1
numberOfTouchesRequired: 1
cancelTouchesInView: YES
delayTouchesBegan: NO
delayTouchesEnded: YES
The Scroll View (relevant) properties are as follows:
userInteractionEnabled: YES
canCancelContentTouches: YES
However, when I tap anywhere on the Scroll View, the gesture does not work.
The delegate class (conforming to UIGestureRecognizerDelegate) must implement
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
This way, the tap gesture will work.
The scroll view has it's own gesture recognizer.
You'll need to override that gesture recognizer or disable that first.
Then and then only, your gesture recognizer will work.
The better way to do this is to use the tap gesture inside the scroll view rather than adding your gesture recognizer.
I am using a tap gesture on my view which also has a table view as a subview. The table does scroll but when tapped, instead of calling didSelectRowAtIndexPath it calls the selector associated with the tap gesture. I can detect the tapped view by getting tap location.
I want to access didSelectRowAtIndexPath when tapped on table instead of the tap gesture selector. How do I achieve this?
Implement the tap gesture's UIGestureRecognizerDelegate , and prevent the gesture if touch is in the tableview.
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
CGPoint p = [gestureRecognizer locationInView:view] ;
if (CGRectContainsPoint(tableview.frame, p)) {
return NO ;
}
return YES ;
}
I currently have a setup of:
A RootVC, with a UIPanGestureRecognizer on self.view. Then the RootVC has a child UITableViewController and hence UITableViewController.view is a subview of self.view.
The cells on the UITableViewController also have gesture recognizers enabling them to be swiped sideways. This works perfectly when the UITableViewController is itself the root view controller.
My issue is that im trying to pass a specific gesture from the self.view gesture recognizer down to the table cells. I've tried delegates:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
and
-(BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer
I can correctly identify the gestures i want to be sent below and return NO in that instance but that seems to cancel the gesture instead of passing it to subviews.
I know i could just call
[self.view.subviews[0] gestureShouldBegin:gestureRecognizer];
But because its the table view cells i cannot determine which cell the gesture should be sent too.
I have been thinking something like
[[self.childViewControllers[0] cellForRowAtIndexPath:indexPath] gestureShouldBegin:gestureRecognizer];
Would work but i dont know how to determine the correct indexPath..
Any ideas?
Look at (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point
You'll need to translate the point of the gesture to the coordinates for the tableView first.