【问题标题】:I've made UIPanGestureRecognizer only detect mostly vertical pans, how do I make it only detect REALLY vertical pans?我已经让 UIPanGestureRecognizer 只检测大部分垂直平底锅,我如何让它只检测真正垂直平底锅?
【发布时间】:2013-04-14 19:52:32
【问题描述】:

我刚刚实现了这个:

- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)panGestureRecognizer {
    CGPoint translation = [panGestureRecognizer translationInView:someView];
    return fabs(translation.y) > fabs(translation.x);
}

(如here所述。)

但如果用户在对角线上垂直平移,它将开始。如何使公差对于它认为垂直的内容更加严格?

基本上,下图描述了我所追求的。第一张图是它现在检测到的,该区域内的任何东西,第二张图是我想要它做的。

【问题讨论】:

    标签: ios objective-c uigesturerecognizer uipangesturerecognizer


    【解决方案1】:

    您可以使用atan2f 给定xy 值来计算垂直角度。例如,要在与垂直方向的角度小于 4 度时开始手势,您可以执行以下操作:

    - (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gesture {
        CGPoint translation = [gesture translationInView:gesture.view];
        if (translation.x != 0 || translation.y != 0) {
            CGFloat angle = atan2f(fabs(translation.x), fabs(translation.y));
            return angle < (4.0 * M_PI / 180.0); // four degrees, but in radians
        }
        return FALSE;
    }
    

    【讨论】:

      【解决方案2】:

      检测纯垂直手势,我假设 translation.x == 0 然后。

      您还应该从您引用的帖子中检查正确答案。他将先前的位置与当前位置进行比较。你可以创造感性。您可以查看我的project,例如查看我使用此敏感性定义的操作何时有效(小于或等于敏感性)或无效(大于敏感性)。检查RPSliderViewController.m内的MOVEMENT_SENSIBILITY

      【讨论】:

      • 这太棒了。当我偶然发现这个问题时,这正是我所需要的。我会将其更改为: if((translation.x > 0) && (translation.x
      【解决方案3】:

      我曾经为此目的编写了一个UIGestureRecognizer 子类。它只跟踪垂直平移。也许这对你有帮助。您可以将其用作任何其他手势识别器,只需设置阈值并在其目标的操作方法中跟踪翻译。

      VerticalPanGestureRecognizer.h

      #import <UIKit/UIKit.h>
      #import <UIKit/UIGestureRecognizerSubclass.h>
      
      @interface VerticalPanGestureRecognizer : UIGestureRecognizer
      
      @property (assign, nonatomic)float translation;
      @property (assign, nonatomic)float offsetThreshold;
      
      @end
      

      VerticalPanGestureRecognizer.m

      #import "VerticalPanGestureRecognizer.h"
      
      @interface VerticalPanGestureRecognizer ()
      {
          CGPoint _startPoint;
      }
      @end
      
      @implementation VerticalPanGestureRecognizer
      
      - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
      {
          if ([touches count] > 1) {
              self.state = UIGestureRecognizerStateFailed;
          }
          else
          {
              _startPoint = [[touches anyObject] locationInView:self.view];
          }
      }
      
      - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
      {
          if (self.state == UIGestureRecognizerStateFailed || self.state == UIGestureRecognizerStateCancelled) {
              return;
          }
          CGPoint currentLocation = [[touches anyObject] locationInView:self.view];
          CGPoint translation;
          translation.x = currentLocation.x - _startPoint.x;
          translation.y = currentLocation.y - _startPoint.y;        
      
          if (self.state == UIGestureRecognizerStatePossible)
          {
              //if the x-translation is above our threshold the gesture fails 
              if (fabsf(translation.x) > self.offsetThreshold)
                  self.state = UIGestureRecognizerStateFailed;
              //if the y-translation has reached the threshold the gesture is recognized and the we start sending action methods
              else if (fabsf(translation.y) > self.offsetThreshold)
                  self.state = UIGestureRecognizerStateBegan;
      
              return;                
          }        
          //if we reached this point the gesture was succesfully recognized so we now enter changed state
          self.state = UIGestureRecognizerStateChanged;
      
          //we are just insterested in the vertical translation
          self.translation = translation.y;
      }
      
      - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
      {
          //if at this point the state is still 'possible' the threshold wasn't reached at all so we fail
          if (self.state == UIGestureRecognizerStatePossible)
          {
              self.state = UIGestureRecognizerStateFailed;
          }
          else
          {
              CGPoint currentLocation = [[touches anyObject] locationInView:self.view];
              CGPoint translation;
              translation.x = _startPoint.x - currentLocation.x;
              translation.y = _startPoint.y - currentLocation.y;
              self.translation = translation.y;
              self.state = UIGestureRecognizerStateEnded;
          }
      
      }
      
      - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
      {
          self.state = UIGestureRecognizerStateCancelled;
      }
      
      - (void)reset
      {
          [super reset];
          _startPoint = CGPointZero;
      }
      
      @end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-10-20
        • 2018-02-09
        • 2017-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多