【问题标题】:Swipe detection in any angle任意角度滑动检测
【发布时间】:2011-10-22 23:20:14
【问题描述】:

有什么方法可以检测到 iPhone 中任何角度的滑动? UISwipeGestureRecognizer 似乎只有 4 个方向。
如果我这样滑动:

\
 \
  \
   X

我希望它能给我带来 60 度的温度,而不是像 UISwipeGestureRecognizer 那样向下倾斜。
我该怎么做?

【问题讨论】:

    标签: ios gesture-recognition


    【解决方案1】:

    您可以使用UIPanGestureRecognizer。当您检测到 Ended 状态时,您可以获得速度。速度分为 x 和 y 分量。您可以使用 x 和 y 分量来计算斜率 m。

    m = Δy / Δx

    由斜率 m 定义的直线的角度 ? 相对于 x 轴的定义如下:

    ? = arctan(m)

    类似:

    - (void)didPan:(UIPanGestureRecognizer*)recognizer {
        switch (recognizer.state) {
            case UIGestureRecognizerStateBegan:
                ...
                break;
    
            case UIGestureRecognizerStateEnded:
                CGPoint velocity = [recognizer velocityInView:[recognizer.view superview]];
                // If needed: CGFloat slope = velocity.y / velocity.x;
                CGFloat angle = atan2f(velocity.y, velocity.x);
                ...
                break;
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以只检测触摸的开始和停止,并计算两个点的角度。

      -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
      //global CGPoint.
          //this should be it's GLOBAL coordinates, not just relative to the view    
          startPoint=[[touches anyObject] locationInView:self.superview.superview];
      }
      -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
          //global CGPoint
          endPoint=[[touches anyObject] locationInView:self.superview.superview];
      }
      

      要计算它们之间的角度,您可以使用以下方法:

      static inline CGFloat angleBetweenLinesInRadians(CGPoint line1Start, CGPoint line1End, CGPoint line2Start, CGPoint line2End) {
      
          CGFloat a = line1End.x - line1Start.x;
          CGFloat b = line1End.y - line1Start.y;
          CGFloat c = line2End.x - line2Start.x;
          CGFloat d = line2End.y - line2Start.y;
      
          CGFloat line1Slope = (line1End.y - line1Start.y) / (line1End.x - line1Start.x);
          CGFloat line2Slope = (line2End.y - line2Start.y) / (line2End.x - line2Start.x);
      
          CGFloat degs = acosf(((a*c) + (b*d)) / ((sqrt(a*a + b*b)) * (sqrt(c*c + d*d))));
          return (line2Slope > line1Slope) ? degs : -degs;    
      }
      //This code came from someone else and I don't remember who to give credit to.
      

      所以要找到水平线的角度,你可以这样做

      CGFloat angle=angleBetweenLinesInRadians(startPoint, endPoint, startPoint, CGPointMake(startPoint.x + 10, startPoint.y));
      

      应该是这样的角度

      ________
      \ this angle
       \
        \
         x
      

      希望对你有帮助

      编辑更好的方法

      你可以做的是子类 UIGestureRecognizer

      #import <UIKit/UIGestureRecognizerSubclass.h>
      

      然后你实现这些方法

      - (void)reset;
      - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
      - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
      - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
      - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
      

      每一个都用于确定和设置手势的状态属性。

      这里有一个完整的例子: http://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/GestureRecognizers/GestureRecognizers.html

      【讨论】:

      • 好吧,我想如果没有内置任何东西,我可以做到这一点。但是为什么要这么麻烦地获得角度呢? atan2(deltaY, deltaX) 为您提供象限和水平/垂直考虑的角度。
      • 那肯定会更好。我已经有了该代码,因为我必须找到围绕中心点滑动的角度。但这会干净得多。
      • 你也可以继承 UIGestureRecognizer
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多