简体   繁体   中英

Tell ScrollView to Scroll after other pan gesture

I'm having trouble getting a scrollview (within a table view) to scroll. Basically, I have an if statement which checks if horizontal movement is greater than vertical movement. If it is, a pan gesture is executed on the cell. Else, I would like the tableview to scroll as normal. I've tried using some variation of self.scrollview.enabled = yes but I couldn't get it working.

It works fine for the horizontal pan gesture, but I can't get it to scroll properly in the else section. Here's the most relevant code: (sorry if it's terrible - I'm still new to iOS/Objective C). Oh and if you see a strange 'code' randomly in the code extract, ignore it - I had some trouble formatting and I lost a word.

-(void)handlePan:(UIPanGestureRecognizer *)panGestureRecognizer
{
    CGPoint location = [panGestureRecognizer locationInView:_tableView];

    //Get the corresponding index path within the table view
    NSIndexPath *indexPath = [_tableView indexPathForRowAtPoint:location];
    TVTableCell *cell = [_tableView cellForRowAtIndexPath:indexPath];

    CGPoint translation = [panGestureRecognizer translationInView:cell];
    // Check for horizontal gesture
    if (fabsf(translation.x) > fabsf(translation.y)) {
        CGPoint originalCenter = cell.center;

        if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) {
            NSLog(@"pan gesture started");
        }

        if (panGestureRecognizer.state == UIGestureRecognizerStateChanged) {
            // translate the center

            CGPoint translation = [panGestureRecognizer translationInView:self.view];
            if (translation.x > 0) {
                cell.center = CGPointMake(originalCenter.x + (translation.x-(translation.x-3)), originalCenter.y);
            } else {
                cell.center = CGPointMake(originalCenter.x + (translation.x-(translation.x+3)), originalCenter.y);
            }

            // determine whether the item has been dragged far enough to initiate a delete / complete
            //this will be implemented eventually
            //  _deleteOnDragRelease = self.frame.origin.x < -self.frame.size.width / 2;
            NSLog(@"state changed");
        }


        if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) {
            // the frame this cell would have had before being dragged
            CGRect originalFrame = CGRectMake(0, cell.frame.origin.y,
                                              cell.bounds.size.width, cell.bounds.size.height);
            //    if (!_deleteOnDragRelease) {
            // if the item is not being deleted, snap back to the original location
            [UIView animateWithDuration:0.2
                             animations:^{
                                 cell.frame = originalFrame;

                             }
             ];

        }
    } else {
        //else: scroll tableview normally
        NSLog(@"dear god act normally");
    }
}

Thanks for the help, all suggestions are very welcome.

I'm not really fond on UITableView but I guess the problem is that assigning your custom UIPanGestureRecognizer to _tableView you're basically invalidating the default one. Anyway whatever the reason you can solve it this way.

Let's assume you do everything in the ViewController, even if it's quite dirty.

Make your ViewController conform the UIGestureRecognizerDelegate protocol

In your ViewController.m override the gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: method.

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

As the documentation says:

Asks the delegate if two gesture recognizers should be allowed to recognize gestures simultaneously.

Return Value
YES to allow both gestureRecognizer and otherGestureRecognizer to recognize their gestures simultaneously. The default implementation returns NO—no two gestures can be recognized simultaneously.

This way both your pan recognizer and the default UITableView one will run.

Last thing you need to do is to set the ViewController as the delegate for the UIPanGestureRecognizer :

UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
panRecognizer.delegate = self;

Note: This is the fastes and dirtiest solution you could implement. A better solution could be to shift the gesture tracking logic into the cell itself, or subclass the UIPanGestureRecognizer . Take a look at this answer too.

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