Disable horizontal scrolling on UITableViewCell when UITableView is still scrolling vertically
I added UIPanGestureRecognizer
to my subclass UITableViewCell
so that when the user navigates to the left, the buttons at the bottom will open (sort of like in the Mail app). I am doing this in awakeFromNib
:
// Add a pan gesture recognizer to the pannable view.
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panScrollView:)];
panGesture.delegate = self;
[self.pannableView addGestureRecognizer:panGesture];
I want to allow table scans despite my own gesture recognizer, so I also have the following in the same subclass UITableViewCell
:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
Now my problem is that I don't know how to only allow one gesture recognizer at a time, so that when the user does two-way validation, the table view doesn't scroll, and vice versa. Help?
What I have tried that doesn't work
Method 1
Implement a UIGestureRecognizerDelegate in the table view manager and request the failure of any gesture recognizer other than vertical that is designed to scroll the table view.
-
Install the table delegate
panGestureRecognizer
on the view controller that contains it (sayContainingViewController
).self.tableView.panGestureRecognizer.delegate = self;
-
Make an
ContainingViewController
implementationUIGestureRecognizerDelegate
. - Enter
shouldRequireFailureOfGestureRecognizer:
and return YES (which I assumeotherGestureRecognizer
will be a horizontal pan gesture).
Error: "UIScrollView embedded in gesture recognizer must have scroll view as its delegate. '
source to share
Create a bool that allows your panGesture to act internally panScrollView
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
self.blockPanGesture = YES;
}
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
self.blockPanGesture = NO;
}
Then
-(void)panScrollView:(UIPanGestureRecognizer *)panGestureRecognizer
{
if(self.blockPanGesture == NO)
{
// do the stuff
}
}
If you pan the whole table completely, I would put the gesture recognizer on the tableView directly ... Otherwise there is also
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return YES if you want the specified item to be editable.
return YES;
}
which handles all of this for you ... but I'm guessing there is a reason why you don't want to use this. You can use this logic as well, for example you might want to customize when the scrollView can also be dragged by putting similar checks in -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
, etc.
source to share
Using Magoo's solution I did something similar that works for me. Hope this helps someone.
In controller class
#pragma mark - UIScrollViewDelegate methods
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
ApplicationDelegate.blockPanGesture = YES;
}
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
ApplicationDelegate.blockPanGesture = NO;
}
Inner cell:
- (IBAction)panGestureRecognizer:(UIPanGestureRecognizer *)panGesture
{
if(ApplicationDelegate.blockPanGesture)
return;
// do your stuff
}
Just FYI: dragged UIPanGestureRecognizer into cell xib file and created above IBOutletAction | panGestureRecognizer: |
source to share