繁体   English   中英

在设置requireGestureToFail后,将UIPanGestureRecognizer和UISwipeGestureRecognizer添加到同一视图会导致冲突

[英]Adding a UIPanGestureRecognizer and a UISwipeGestureRecognizer to same view causes conflicts after setting requireGestureToFail

我在同一个视图中添加了一个滑动手势识别器和一个平移手势识别器。 这些手势应该是彼此独有的。

为了做到这一点,我在滑动手势上添加了约束

[swipeGesture requireGestureToFail:panGesture];

(因为平移手势应该优先)

问题是总是调用平移手势 - 即使在非常快速的滑动过程中也是如此。

为了克服这个问题,我把自己定位为泛手势的代表。 在委托方法中,我设置了一些代码,如下所示:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    // check if it is the relevant view
    if (gestureRecognizer.view == self.myViewWithTwoGestures)
    {
        // check that it is the pan gesture
        if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
        {
            UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer;
            CGPoint velocity = [pan velocityInView:gestureRecognizer.view];
            // added an arbitrary velocity for failure
            if (ABS(velocity.y) > 100)
            {
                // fail if the swipe was fast enough - this should allow the swipe gesture to be invoked
                return NO;
            }
        }
    }
    return YES;
}

是否有建议的速度来确保良好的行为? 还有另一种方法可以强制平移手势失败吗?

根据苹果的文档这里 (下声明一个特定的顺序为两个姿势识别器 ),以获得这两种方式UIPanGestureRecognizerUISwipeGestureRecognizer在同一个视图中工作是通过要求UISwipeGesureRecognizer调用之前失败UIPanGestureRecognizer (你写的正好相反)。 这可能与滑动手势也是平移手势的事实有关,但相反的情况不一定如此(参见此SO问题)。

我写了这段小代码,它设法识别平移和滑动手势:

UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panned:)];
UISwipeGestureRecognizer * swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swiped:)];
[pan requireGestureRecognizerToFail:swipe];
swipe.direction = (UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight);

-(void)panned:(UIPanGestureRecognizer *)gesture
{
    NSLog(@"Pan");
}

-(void)swiped:(UISwipeGestureRecognizer *)gesture
{
    NSLog(@"Swipe");
}

这并不像你希望的那样好(因为你需要滑动手势失败,在平移手势开始之前有一个小延迟),但它确实有效。 但是,您发布的代码可让您根据自己的喜好微调手势。

迟到的回复,但我有一个类似的问题,我想在刷卡之前平移识别。 我能让它工作的唯一方法是使用长按(或类似的东西)来设置标志以将平移手势用作平移或滑动。 我最后根本没有使用滑动。 即:

- (void) handleLongPress : (UILongPressGestureRecognizer *) gestureRecognizer
{
    if (gestureRecognizer.state == UIGestureRecognizerStateBegan)
    {
        _canSwipe = YES;
    }
    else if (gestureRecognizer.state == UIGestureRecognizerStateEnded)
    {
        _canSwipe = NO;
    }
}

- (void) handleDragging : (id) sender
{
    UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)sender;
    GLKVector2 dragDelta = GLKVector2Make(0., 0.);

    if (pan.state == UIGestureRecognizerStateBegan || pan.state == UIGestureRecognizerStateChanged)
    {
        _mousePosition = [pan translationInView:self.view];
        if (_beginDragging == NO)
        {
            _beginDragging = YES;
        }
        else
        {
            dragDelta = GLKVector2Make(_mousePosition.x - _prevMousePosition.x, _mousePosition.y - _prevMousePosition.y);
        }

        _prevMousePosition = _mousePosition;
    }
    else
    {
        _beginDragging = NO;
    }

    if (_canSwipe == YES)
    {
        if (dragDelta.x > 0)
        {
            _canSwipe = NO;
            [self.navigationController popToRootViewControllerAnimated:YES];
            NSLog(@"swipe right");
        }
        else if (dragDelta.x < 0)
        {
            _canSwipe = NO;
            [self performSegueWithIdentifier:@"toTableSegue" sender:pan];
            NSLog(@"swipe left");
        }
    }
    else
    {
        _dragDeltaTranslation = GLKVector2Make(dragDelta.x/90, dragDelta.y/90);
        _translationXY = GLKVector2Make(_translationXY.x + _dragDeltaTranslation.x, _translationXY.y - _dragDeltaTranslation.y);
    }
}

基本上:

  1. 使用长按(或其他一些机制)来激活滑动状态(长按很好,因为一旦释放,状态就会转到UIGestureRecognizerStateEnded)
  2. 然后使用平移方向确定滑动的方向。 2。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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