【问题标题】:How to implement one-finger rotate gesture recognizer?如何实现单指旋转手势识别器?
【发布时间】:2010-08-27 01:44:38
【问题描述】:

我知道 UIRotateGestureRecognizer 已经是 iOS 的一部分。但这个手势需要两根手指。如何实现只需要一根手指的类似手势识别器? AppStore 中有一款游戏 - Gyrotate 很好地实现了这一点。任何线索表示赞赏。谢谢。

【问题讨论】:

  • Just FWIW - 最好的方法是从根本上理解,如果切线的导数是平滑的,那么它可能是用户正在绘制的一个很好的圆弧。从概念上讲,切线的导数很容易计算,并且只需要很少的状态——您只需要检查最后两帧!这是识别弧段的“神奇”算法。

标签: iphone gesture-recognition


【解决方案1】:

Kirby Turner 拥有完整的单指旋转手势识别器here

【讨论】:

  • 如何使用此代码执行旋转和平移?
  • 您一直在询问是否要执行“两者”。如果您想检测两个单独的手势,只需使用两个(或更多)UIGestureRecogniser。
【解决方案2】:

这是代码 - 它适用于我的模拟器。如果那是您要找的,马克回答了。

    // On new touch, start a new array of points
- (void) touchesBegan:(NSSet *) touches withEvent:(UIEvent *) event
{
    self.points = [NSMutableArray array];
    CGPoint pt = [[touches anyObject] locationInView:self];
    [self.points addObject:[NSValue valueWithCGPoint:pt]];
}

// Add each point to the array
- (void) touchesMoved:(NSSet *) touches withEvent:(UIEvent *) event
{
    CGPoint pt = [[touches anyObject] locationInView:self];
    [self.points addObject:[NSValue valueWithCGPoint:pt]];
    [self setNeedsDisplay];
}

// At the end of touches, determine whether a circle was drawn
- (void) touchesEnded:(NSSet *) touches withEvent:(UIEvent *) event
{
    if (!self.points) return;
    if (self.points.count < 3) return;

    // Test 1: The start and end points must be between 60 pixels of each other
    CGRect tcircle;
    if (distance(POINT(0), POINT(self.points.count - 1)) < 60.0f)
        tcircle = [self centeredRectangle];

    // Test 2: Count the distance traveled in degrees. Must fall within 45 degrees of 2 PI
    CGPoint center = CGPointMake(CGRectGetMidX(tcircle), CGRectGetMidY(tcircle));
    float distance = ABS(acos(dotproduct(centerPoint(POINT(0), center), centerPoint(POINT(1), center))));
    for (int i = 1; i < (self.points.count - 1); i++)
        distance += ABS(acos(dotproduct(centerPoint(POINT(i), center), centerPoint(POINT(i+1), center))));
    if ((ABS(distance - 2 * M_PI) < (M_PI / 4.0f))) circle = tcircle;

    [self setNeedsDisplay];
}

【讨论】:

  • 不是什么解决了我的问题,而是触发了我的终极解决方案。
  • 啊完美,这正是我想要的,也是
  • 实际上我想假设我执行旋转操作然后我想将对象转换到屏幕的其他位置,那么我该如何处理这段代码?
  • @amok 是 centeredRectangle 和 setNeedsDisplay 用户定义的方法吗?如果是的话,你能提供那个代码吗
【解决方案3】:

我用 OneFingerRotationScaleResizeClose 功能实现了 IQStickerView .

特点:-

1) 单指旋转刻度。

2) 单指调整大小。

3) 使用属性启用/禁用旋转、缩放、调整大小。

4) 自动管理多个 IQStickerView。

5) 也可以与 UIScrollView 一起使用。

6) 快速响应。

github 仓库在这里:- https://github.com/hackiftekhar/IQStickerView

【讨论】:

    【解决方案4】:

    尝试探索UIGestureRecognizer Class。您应该可以使用 UIGestureRecognizerDelegate 自定义它

    【讨论】:

      【解决方案5】:

      使用平移手势识别器实现,这是使用手势识别器附加到的另一个 UIView,但它应该与附加到要旋转的视图一起使用。

      - (void) gestureRotateButtonPan:(UIPanGestureRecognizer*) gestureRecognizer {
      
          switch (gestureRecognizer.state) {
              case UIGestureRecognizerStatePossible:
                  break;
              case UIGestureRecognizerStateBegan:
              {
                  CGPoint location = [gestureRecognizer translationInView:[gestureRecognizer view]];
                  _touchRotateStartPoint = [self convertPoint:location fromView:[gestureRecognizer view]];
              }
                  break;
              case UIGestureRecognizerStateChanged:
              {
                  CGPoint imageLocation = CGPointMake(self.mainImageView.transform.tx + self.mainImageView.center.x
                                                      , self.mainImageView.transform.ty + self.mainImageView.center.y);
                  CGPoint buttonLocation = [gestureRecognizer translationInView:self];
                  buttonLocation.x += _touchRotateStartPoint.x;
                  buttonLocation.y += _touchRotateStartPoint.y;
      
                  CGFloat currentRotation = atan2(buttonLocation.y - imageLocation.y, buttonLocation.x - imageLocation.x)
                                              - atan2(_touchRotateStartPoint.y - imageLocation.y, _touchRotateStartPoint.x - imageLocation.x);
      
                  CGFloat rotation = -(_lastRotation - currentRotation);
                  CGAffineTransform currentTransform = self.mainImageView.transform;
                  CGAffineTransform rotatedTransform = CGAffineTransformRotate(currentTransform, rotation);
                  self.mainImageView.transform = rotatedTransform;
      
                  [self setNeedsDisplay];
              }
                  break;
              case UIGestureRecognizerStateCancelled:
              case UIGestureRecognizerStateEnded:
                  _lastRotation = 0.0;
                  break;
              case UIGestureRecognizerStateFailed:
                  break;
              default:
                  break;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-15
        • 2018-02-01
        • 1970-01-01
        • 2018-01-19
        • 2013-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多