2012-08-08 25 views
6

Tôi đã đọc một loạt câu hỏi về điều này nhưng không ai trong số họ dường như đạt được những gì tôi đang tìm kiếm ... Vì vậy, hãy nói rằng tôi có một tùy ý UIWebView bên trong một số UIViewController. UIViewController có một số SwipeGestureRecognizer hoạt động tốt. Nó thậm chí hoạt động trong UIWebView - bất cứ khi nào không có thanh cuộn. (Trước khi tôi tải một trang hoặc thậm chí nếu tôi tải một trang có thể vừa với kích thước phù hợp với kích thước của UIWebView). Tuy nhiên, nếu tôi tải trang web yêu cầu di chuyển ngang sang trái hoặc phải, thì bên trong phần UIWebView trong chế độ xem của tôi, tôi không thể nhận được bất kỳ cử chỉ vuốt nào được nhận dạng. Mỗi lần nhấp/kéo/vuốt chỉ kích hoạt hành động cuộn. Có cách nào để phân biệt giữa một "swipe" và chỉ cần di chuyển bằng ngón tay của bạn (không phải nâng nó mà là kéo để di chuyển).Nhận diện cử chỉ vuốt bên trong UIWebView

Trả lời

2

Bạn sẽ phải phân lớp UIWebView và ghi đè các cuộc gọi nhận dạng cử chỉ.

EDIT - Nhìn vào bài này Handling touches inside UIWebview và liên kết này http://mithin.in/2009/08/26/detecting-taps-and-events-on-uiwebview-the-right-way/

+2

Bạn có thể mô tả cách thực hiện việc này không? Trong tài liệu, nó nói "Lớp UIWebView không nên được phân lớp". http://developer.apple.com/library/ios/#documentation/uikit/reference/UIWebView_Class/Reference/Reference.html – MrHappyAsthma

+0

Nhìn vào chỉnh sửa –

24

Vâng, bạn có thể nói UIScrollView của UIWebView rằng UIPanGestureRecognizer của nó nên chỉ cháy khi UISwipeGestureRecognizer của riêng bạn đã thất bại.

Đây là cách bạn làm điều đó:

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]; 

Điều đó sẽ làm các trick cho bạn.

+1

Hoạt động vừa phải. –

+1

Genius, đã tiết kiệm rất nhiều thời gian của tôi! –

+1

Tôi chưa thử nghiệm điều này nhưng tôi nghĩ nó sẽ ghi đè lên việc cuộn mặc định của UIWebview. Phải không? –

1

Johannes Fahrenkrug's answer đã thành công trong việc chặn các cử chỉ di chuyển được tích hợp sẵn của webView. Tuy nhiên, tôi thấy rằng điều này chỉ hoạt động nếu cử chỉ pan của webView rất chậm ... nếu tôi duyệt webView với bất kỳ tốc độ hợp lý nào, cử chỉ vuốt được kích hoạt. Tôi chỉ muốn vuốt nhanh để kích hoạt cử chỉ vuốt và chảo trung bình hoặc chậm để sử dụng chức năng cuộn webView mặc định.

Các UISwipeGestureRecognizer không có đặc tính để tùy chỉnh tốc độ của một swipe, và UIPanGestureRecognizer có một tài sản vận tốc nhưng không có cách nào để thiết lập một tốc độ cần thiết, vì vậy tôi thiết lập một trình nhận dạng cử chỉ tùy chỉnh dựa trên 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 

Thiết lập cử chỉ của bạn

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

Sau đó phát hiện sự chỉ đạo của cử chỉ nhận

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

Lưu ý rằng điều này chỉ đòi hỏi một cử chỉ để xử lý tất cả bốn hướng swipe, thay vì một UISwipeGestureRecognizer cho mỗi hướng.

Các vấn đề liên quan