4

我添加了一個滑動手勢識別器和平移姿勢識別器到相同的視圖後的衝突。這些手勢應該是相互排斥的。添加UIPanGestureRecognizer和UISwipeGestureRecognizer到同一視圖導致設置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; 
} 

是否有建議的速度以確保良好的行爲?是否有另一種方法來強制平移手勢失敗?

+1

你有沒有試過' - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer'方法,'返回YES;'? – Akhilrajtr

+0

我不想同時這就是爲什麼我在問題中寫下「獨佔」 –

回答

10

根據蘋果的文檔here下宣告了兩個姿勢識別特定的順序)的方式來獲得兩個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"); 
} 

這並不工作,以及你希望(因爲你需要滑動手勢失敗在平移手勢開始之前有一個小的延遲),但它確實有效。 您發佈的代碼可讓您根據自己的喜好微調手勢。

1

晚迴應,但我有一個類似的問題,我想平移的刷卡之前被識別。唯一能讓它工作的方法是使用長按(或類似的方法)來設置一個標誌,以使用平移手勢作爲平移或滑動。我最終沒有使用滑動。即:

- (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.
相關問題