簡體   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