2012-12-14 13 views
3
之間快速切換

澄清:在Xcode和速度使用UIPanGestureRecognizer確定刷卡方向過於敏感和方向

我想要實現的是:滑動手勢(上,下,左,右)是在WebView上。當發生任何手勢時,這就是它需要發生的事情:一旦滑動開始,就必須開始一個動作(動作實際上是加載一個HTML鏈接,它將ip攝像頭移動到上,下,右,左)。 html鏈接使攝像機一路向右或向左或向上或向下。我有另一個HTML鏈接,當加載將告訴IP攝像頭停止。

所以它需要發生什麼事是當狀態是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

如果x組件是y組件的一些合理的倍數,您可以進行一些「水平」方向檢測。所以,如果xy的五倍,那可以被認爲是水平滑動。反之亦然。五個是否合適取決於您(使用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 

這表明你怎麼能確定平移手勢的初始方向,然後一旦建立初始方向,以及基於手勢的結束動作。

+0

好的,這個解決方案能正確識別右,左,上,下,但我的其他問題仍然存在。一旦識別到有效的刷卡並立即結束,即使手指仍在刷卡,觸發我的其他操作,操作立即開始。我的第一個動作就是在我開始滑動時開始第一個動作,並且只在手指關閉時觸發第二個動作纔開始動作。 – Dashony

+0

感謝解決方案Rob,因爲我的刷卡問題,現在滑動方向被正確識別,只觸發一次而不是15次。我上面的代碼的一個大問題是,現在它不能識別我的手指離開了屏幕,所以只有在通過將手指從屏幕上擡起來完成滑動時纔會調用UIGestureRecognizerStateEnded,然後我的第二個動作開始。希望我清楚,如果沒有,我會盡力給更多的信息。 – Dashony

+0

感謝您對我進行編輯。我正要去但我注意到你做到了。所以謝謝 – Dashony

1

首先,您可以使用平移而不是手勢的速度 - 這會讓您從滑動的開始到結束行進的距離,而不是滑動結束時的移動方向,如與速度。其次,在檢查方向之前,您可能應該檢查手勢狀態是否爲「已結束」。現在你在每個'if'中重複同樣的檢查。

要獲得方向,您可以使用atan2三角函數和平移的x和y來獲取平移的角度,或者如果可以始終將手勢解釋爲4個方向之一的滑動,只需查找x或者y具有更大的絕對值,然後如果它是正值或負值。

+0

OP可能不想檢查手勢的結束,否則使用滑動手勢會更好;這是OP正試圖解決的奇怪問題。就我個人而言,我認爲他應該使用標準的'UISwipeGestureRecognizer',因爲OP的期望手勢非常不規範(通常用戶應該始終有能力在開始時有效地取消手勢,而OP的解決方案不提供)。但每一個他自己。 – Rob

+0

你是對的,但是從我得到的東西他希望在手勢過程中和結束時識別方向。這使我的第二點無效,至於使用翻譯,我不確定他是否想要從一開始或在任何特定時刻測量運動的方向。當談到測量方向時,你的答案確實完全沒問題。我只能補充一點,爲了減少方向的「隨機性」,他可以將最後幾個手勢位置保存爲一個歷史記錄,並將最後一個手勢位置與之前的第n個手勢位置進行比較。 – konrad

+0

同意。我更新了我的答案,讓手勢識別器在成功識別手勢後立即取消自己,以確保您不會發生任何無關識別,例如用戶將手指從屏幕上擡起。 – Rob