简体   繁体   中英

Disable horizontal scrolling on UITableViewCell when UITableView is still scrolling vertically

I added a UIPanGestureRecognizer on my UITableViewCell subclass so that when the user swipes to the left, the buttons underneath are revealed (kind of like in the Mail app). I do 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 the table view to scroll despite my custom gesture recognizer so I also have the following in the same UITableViewCell subclass:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

My problem now is I don't know how to allow only one gesture recognizer at a time, so that when the user is side-swiping, the table view doesn't scroll, and vice versa. Help?


What I've tried that doesn't work

Method 1

Implement UIGestureRecognizerDelegate in the table view's view controller and require the failure of any other gesture recognizer besides the vertical one which is for scrolling the table view.

  1. Set the table view's panGestureRecognizer 's delegate to the view controller that contains it (say it's ContainingViewController ).

     self.tableView.panGestureRecognizer.delegate = self; 
  2. Make ContainingViewController implement UIGestureRecognizerDelegate .

  3. Implement shouldRequireFailureOfGestureRecognizer: and return YES (I'm assuming that the otherGestureRecognizer will be the horizontal panning gesture).

Error: 'UIScrollView's built-in pan gesture recognizer must have its scroll view as its delegate.'

Create a bool that allows your panGesture to action inside 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 are panning the entire tableview personally I'd put the gesture recogniser on the tableView itself... Otherwise there's also

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {

    // Return YES if you want the specified item to be editable.
    return YES;
}

which handles all this for you... but I'm assuming there's a reason you don't want to use this. You can also build on this logic, for example you might want to tweak when the scrollView can drag as well, by putting similar checks in -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView etc.

Using Magoo solution, I did something simillar which works for me. Hope it 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;
}

Inside Cell:

- (IBAction)panGestureRecognizer:(UIPanGestureRecognizer *)panGesture
{
    if(ApplicationDelegate.blockPanGesture)
        return;

    // do your stuff

}

Just FYI: have dragged UIPanGestureRecognizer in Cell's xib file and created above IBOutletAction |panGestureRecognizer:|

您是否尝试将跳出属性设置为NO?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM