ios - 在 Xcode 中使用 UIPanGestureRecognizer 和速度来确定滑动方向过于敏感并且在方向之间快速切换

标签 ios xcode uipangesturerecognizer swipe-gesture

澄清:

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

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


原始问题:

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

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

任何帮助将不胜感激。这是我的代码:

在 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 }
}

谢谢,任何澄清请询问。

最佳答案

如果 x 组件是 y 组件的某个合理倍数,您可以进行一些“水平”方向检测。因此,也许如果 xy 的五倍,则可以将其视为水平滑动。垂直方向反之亦然。 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

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

关于ios - 在 Xcode 中使用 UIPanGestureRecognizer 和速度来确定滑动方向过于敏感并且在方向之间快速切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13873827/

相关文章:

swift - SpriteKit 中的 UIPanGesture

ios - Xcode 10 - 无法构建 React Native 应用程序

ios - 使用 Storyboard的多节 UITableView

ios - MVP 架构模式示例。 swift

ios - 在创建时停止 UIViewController 的自动旋转

ios - UIScreenEdgePanGestureRecognizer 无法处理方向更改?

ios - 我是否必须购买域才能运行我的应用程序,该应用程序在 AWS 服务器上使用 EC2 实例以使用 HTTPS?

ios - 无法在属性初始值设定项中使用实例成员 'server'

objective-c - 什么是 [super awakeFromNib];用于?

ios - 尝试将平移手势应用于 UITableViewCell 但失败了,为什么?