3

澄清:

我想要实现的是:滑动手势(向上、向下、向右和向左)在 WebView 上。当任何手势发生时,这就是它需要发生的事情:一旦开始滑动,就必须开始一个动作(该动作实际上是加载一个 html 链接,该链接将 ip 摄像头移动到上、下、右、左)。html链接使相机一直向右或向左或向上或向下。我有另一个 html 链接,加载时会告诉网络摄像机停止。

所以它需要发生的是当状态是 UIGestureRecognizerStateBegan 链接加载并不断移动相机直到用户没有触摸屏幕并且状态变为 UIGestureRecognizerStateEnded 并触发另一个 html 链接在 WebView 中运行哪个链接将停止相机从移动。正如我们所说,我发布的初始代码就是这样做的,但是刷卡太敏感了。您的代码已解决此问题,但现在第二个链接在第一个链接之后立即加载,不允许相机移动。是否有意义??第一个链接需要运行直到手指被抬起。


原始问题:

我试图使用我管理的 UIPanGestureRecognizer 中的速度来确定滑动方向,它检测到向右、向左、向上和向下滑动,它会根据滑动方向触发适当的操作,并在每次滑动时再次触发正确的操作 UIGestureRecognizerStateEnded ,但是,我在下面的代码中的问题是方向非常敏感,例如在向右滑动期间,它可以识别大部分向右滑动,但也可以在两者之间向上或向下滑动。由于滑动并不总是完美地在一条直线上,我想发现的是,如果滑动大部分是向右,则只触发向右滑动的动作,并忽略微小的像素偏差。

此外,对于我的项目来说,理想情况下是只触发一次给定滑动方向上的动作,就像在 UISwipeGestureRecognizer 中一样,但是使用它我遇到了 UIGestureRecognizerStateEnded 的问题,因为它不会让滑动动作运行,直到我将手指从屏幕,即使我的手指仍在滑动,它也会立即完成滑动动作。

任何帮助将非常感激。这是我的代码:

在 ViewDidLoad 我有:

UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
[_myWebView addGestureRecognizer:gestureRecognizer];
[gestureRecognizer setMinimumNumberOfTouches:1];
[gestureRecognizer setMaximumNumberOfTouches:1];

在我的课堂上,我有:

- (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer
{
CGPoint velocity = [gestureRecognizer velocityInView:_myWebView];

if(velocity.x > 0)//right
{
   //my action here

  if ( [gestureRecognizer state] == UIGestureRecognizerStateEnded )
  { //my action when swipe finished here }
}
else if(velocity.x < 0)//left
{
   //my action here

  if ( [gestureRecognizer state] == UIGestureRecognizerStateEnded )
  { //my action when swipe finished here }
}
else if(velocity.y > 0)//down
{
   //my action here

  if ( [gestureRecognizer state] == UIGestureRecognizerStateEnded )
  { //my action when swipe finished here }
}
else if(velocity.y < 0)//up
{
   //my action here

  if ( [gestureRecognizer state] == UIGestureRecognizerStateEnded )
  { //my action when swipe finished here }
}

谢谢,有什么需要说明的请追问。

4

2 回答 2

4

x如果组件是组件的某个合理倍数,您可以进行一些“水平”方向检测y。所以,如果x是五次y,那可以被认为是水平滑动。垂直方向反之亦然。5 是否是正确的倍数取决于您(使用 tan -1,您可以看到从绝对水平/垂直转换为大约 11.3°),但从概念上讲,这是一种轻松解决它的方法。

例如,这是一个手势识别器,当用户开始向特定方向滑动时,它将向相机发送命令以启动该方向的移动,并在用户将手指从屏幕上抬起时告诉相机停止:

CGFloat const gestureMinimumTranslation = 20.0;

typedef enum : NSInteger {
    kCameraMoveDirectionNone,
    kCameraMoveDirectionUp,
    kCameraMoveDirectionDown,
    kCameraMoveDirectionRight,
    kCameraMoveDirectionLeft
} CameraMoveDirection;

@interface ViewController ()
{
    CameraMoveDirection direction;
}
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
    [self.viewWithGestureRecognizer addGestureRecognizer:recognizer];
}

// This is my gesture recognizer handler, which detects movement in a particular
// direction, conceptually tells a camera to start moving in that direction
// and when the user lifts their finger off the screen, tells the camera to stop.

- (void)handleSwipe:(UIPanGestureRecognizer *)gesture
{
    CGPoint translation = [gesture translationInView:self.view];

    if (gesture.state == UIGestureRecognizerStateBegan)
    {
        direction = kCameraMoveDirectionNone;
    }
    else if (gesture.state == UIGestureRecognizerStateChanged && direction == kCameraMoveDirectionNone)
    {
        direction = [self determineCameraDirectionIfNeeded:translation];

        // ok, now initiate movement in the direction indicated by the user's gesture

        switch (direction) {
            case kCameraMoveDirectionDown:
                NSLog(@"Start moving down");
                break;

            case kCameraMoveDirectionUp:
                NSLog(@"Start moving up");
                break;

            case kCameraMoveDirectionRight:
                NSLog(@"Start moving right");
                break;

            case kCameraMoveDirectionLeft:
                NSLog(@"Start moving left");
                break;

            default:
                break;
        }
    }
    else if (gesture.state == UIGestureRecognizerStateEnded)
    {
        // now tell the camera to stop
        NSLog(@"Stop");
    }
}

// This method will determine whether the direction of the user's swipe

- (CameraMoveDirection)determineCameraDirectionIfNeeded:(CGPoint)translation
{
    if (direction != kCameraMoveDirectionNone)
        return direction;

    // determine if horizontal swipe only if you meet some minimum velocity

    if (fabs(translation.x) > gestureMinimumTranslation)
    {
        BOOL gestureHorizontal = NO;

        if (translation.y == 0.0)
            gestureHorizontal = YES;
        else
            gestureHorizontal = (fabs(translation.x / translation.y) > 5.0);

        if (gestureHorizontal)
        {
            if (translation.x > 0.0)
                return kCameraMoveDirectionRight;
            else
                return kCameraMoveDirectionLeft;
        }
    }
    // determine if vertical swipe only if you meet some minimum velocity

    else if (fabs(translation.y) > gestureMinimumTranslation)
    {
        BOOL gestureVertical = NO;

        if (translation.x == 0.0)
            gestureVertical = YES;
        else
            gestureVertical = (fabs(translation.y / translation.x) > 5.0);

        if (gestureVertical)
        {
            if (translation.y > 0.0)
                return kCameraMoveDirectionDown;
            else
                return kCameraMoveDirectionUp;
        }
    }

    return direction;
}

@end

这演示了如何确定平移手势的初始方向,然后在确定初始方向以及手势结束时采取行动。

于 2012-12-14T07:25:12.603 回答
1

首先,您可以使用平移而不是手势的速度 - 这将为您提供从滑动开始到结束的距离,而不是滑动结束时的移动方向,就像速度一样。

其次,您可能应该在检查方向之前检查手势状态是否为“结束”。现在您在每个“if”中重复相同的检查。

要获得方向,您可以使用带有 x 和 y 平移的 atan2 三角函数来获得平移角度,或者如果可以始终将手势解释为 4 个方向之一的滑动,只需找出 x 或 y 是否更大绝对值,然后是正值还是负值。

于 2012-12-14T14:17:15.940 回答