2012-08-08 225 views
6

我已經閱讀了一堆關於這個問題,但沒有一個人似乎達到我在找什麼...因此,可以說我有一個UIWebView任意UIViewController內。 UIViewController有一個SwipeGestureRecognizer工作正常。它甚至可以在UIWebView內工作 - 只要沒有滾動條。 (在我加載頁面之前,或者即使我加載了一個頁面,可以在我的UIWebView的尺寸範圍內適當放置)。但是,如果我加載需要向左或向右水平滾動的網頁,則在我的視圖的部分內容中,我無法獲取任何輕掃手勢進行識別。每次點擊/拖拽/輕掃只會觸發滾動操作。有沒有辦法區分「滑動」和只用手指滾動(不是解除它,而是拖動滾動)。滑動手勢識別UIWebView

回答

2

您將不得不繼承UIWebView並覆蓋手勢識別器調用。

編輯 - 看看這個帖子Handling touches inside UIWebview而這個鏈接http://mithin.in/2009/08/26/detecting-taps-and-events-on-uiwebview-the-right-way/

+2

你能描述一下怎麼去解決這個問題嗎?在文檔中說「UIWebView類不應該被分類」。 http://developer.apple.com/library/ios/#documentation/uikit/reference/UIWebView_Class/Reference/Reference.html – MrHappyAsthma 2012-08-08 16:51:23

+0

看看編輯 – 2012-08-08 16:56:08

24

是的,你可以告訴一個UIWebView的UIScrollView的,其UIPanGestureRecognizer應該只火的時候自己UISwipeGestureRecognizer失敗。

這是你如何做到這一點:

UISwipeGestureRecognizer *rightSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)]; 
UISwipeGestureRecognizer *leftSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)]; 
rightSwipeGesture.direction = UISwipeGestureRecognizerDirectionRight; 
leftSwipeGesture.direction = UISwipeGestureRecognizerDirectionLeft; 
[self.view addGestureRecognizer:rightSwipeGesture]; 
[self.view addGestureRecognizer:leftSwipeGesture]; 

[_webView.scrollView.panGestureRecognizer requireGestureRecognizerToFail:rightSwipeGesture]; 
[_webView.scrollView.panGestureRecognizer requireGestureRecognizerToFail:leftSwipeGesture]; 

這應該爲你做的伎倆。

+1

工作恰到好處。 – 2013-09-30 15:57:55

+1

天才,救了我很多時間! – 2015-06-25 07:52:35

+1

我沒有測試過這個,但我想它會覆蓋UIWebview的默認滾動。這不正確嗎? – 2016-04-22 08:20:55

1

Johannes Fahrenkrug's answer成功有條件地阻止了webView的內置平移手勢。但是,我發現這隻在webView的平移手勢非常慢時才起作用......如果我以合理的速度平移webView,則會觸發滑動手勢。我只想要快速滑動來觸發滑動手勢,而中等或慢速滑動可以使用默認的webView滾動功能。

的UISwipeGestureRecognizer有定製刷卡的速度沒有屬性,而UIPanGestureRecognizer的速度是財產,但沒有辦法設置要求的速度,所以我建立基於this tutorial自定義手勢識別:

FastSwipeGestureRecognizer.h

#import <UIKit/UIKit.h> 
#import <UIKit/UIGestureRecognizerSubclass.h> 

#define REQUIRED_TOUCHES 5 
#define REQUIRED_STRAIGHTNESS 3 
#define REQUIRED_TIME .1 

typedef enum { 
    DirectionUp = 0, 
    DirectionRight, 
    DirectionDown, 
    DirectionLeft 
} Direction; 

@interface FastSwipeGestureRecognizer : UIGestureRecognizer { 
    CGPoint firstTouchLocation; 
    NSTimeInterval firstTouchTime; 
    int touchesCount; 

    Direction direction; 
} 

@property (nonatomic) CGPoint firstTouchLocation; 
@property (nonatomic) NSTimeInterval firstTouchTime; 
@property (nonatomic) int touchesCount; 

@property (nonatomic) Direction direction; 

@end 

FastSwipeGestureRecognizer.m

#import "FastSwipeGestureRecognizer.h" 

@implementation FastSwipeGestureRecognizer 

@synthesize firstTouchLocation; 
@synthesize firstTouchTime; 
@synthesize touchesCount; 

-(void)reset { 
    [super reset]; 
} 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    [super touchesBegan:touches withEvent:event]; 
    self.firstTouchLocation = [[touches anyObject] locationInView:self.view]; 
    self.firstTouchTime = [NSDate timeIntervalSinceReferenceDate]; 
    self.touchesCount = 1; 
    self.state = UIGestureRecognizerStatePossible; 
} 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    [super touchesMoved:touches withEvent:event]; 
    self.touchesCount++; 
    if (self.touchesCount > REQUIRED_TOUCHES) { // wait until we have a few touches before we evaluate the gesture 
     CGPoint thisTouchLocation = [[touches anyObject] locationInView:self.view]; 
     float horizontalRatio = (ABS(thisTouchLocation.x - self.firstTouchLocation.x)/ABS(thisTouchLocation.y - self.firstTouchLocation.y)); 
     float verticalRatio = 1/horizontalRatio; 
     NSTimeInterval elapsedTime = [NSDate timeIntervalSinceReferenceDate] - self.firstTouchTime; 
     NSLog(@"swipe? %f, %f, %f", verticalRatio, horizontalRatio, elapsedTime); 

     // if we're moving straight enough and fast enough, complete the gesture 
     if (((horizontalRatio > REQUIRED_STRAIGHTNESS)||(verticalRatio > REQUIRED_STRAIGHTNESS))&&(elapsedTime < REQUIRED_TIME)) { 
      if (horizontalRatio > REQUIRED_STRAIGHTNESS) { 
       self.direction = (thisTouchLocation.x > self.firstTouchLocation.x) ? DirectionRight : DirectionLeft ; 
      } else if (verticalRatio > REQUIRED_STRAIGHTNESS) { 
       self.direction = (thisTouchLocation.y > self.firstTouchLocation.y) ? DirectionDown : DirectionUp ; 
      } 
      self.state = UIGestureRecognizerStateRecognized; 
     } else { 
      self.state = UIGestureRecognizerStateFailed; 
     } 
    } 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    [super touchesEnded:touches withEvent:event]; 
    if (self.touchesCount < REQUIRED_TOUCHES) { 
     self.state = UIGestureRecognizerStateFailed; 
    } 
} 

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { 
    [super touchesCancelled:touches withEvent:event]; 
    self.state = UIGestureRecognizerStateFailed; 
} 

@end 

設置你的手勢

FastSwipeGestureRecognizer *swipeGesture = [[FastSwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)]; 
[self.view addGestureRecognizer:swipeGesture]; 
[self.webView.scrollView.panGestureRecognizer requireGestureRecognizerToFail:swipeGesture]; 

然後檢測接收到的手勢

- (void)handleSwipeGesture:(FastSwipeGestureRecognizer *)gesture { 
    if (gesture.state == UIGestureRecognizerStateEnded) { 
     if (gesture.direction == DirectionRight) { 
      // do something 
     } else if (gesture.direction == DirectionLeft) { 
      // do something 
     } else if (gesture.direction == DirectionUp) { 
      // do something 
     } else if (gesture.direction == DirectionDown) { 
      // do something 
     } 
    } 
} 

注意的方向,這個只需要一個手勢來處理所有四個刷卡方向,而不是每個方向一個UISwipeGestureRecognizer。