2012-08-08 8 views
6

나는 이것에 대해 많은 질문을 읽었지 만 그 중 어느 것도 내가 찾고있는 것을 성취하지 못하는 것 같습니다 ... 그래서 나는 UIViewController 안에 임의의 UIWebView이 있다고 말할 수 있습니다. UIViewController에는 잘 작동하는 SwipeGestureRecognizer가 있습니다. 스크롤 바가 없을 때마다 UIWebView에서 작동합니다. (페이지를로드하기 전에 또는 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

+0

수정 –

24

예 봐, 당신은 그 UIPanGestureRecognizer 만 불이 자신의 UISwipeGestureRecognizer가 실패한다 때 그있는 UIWebView의있는 UIScrollView를 알 수 있습니다.

이것은 당신이 그것을하는 방법이다 : 당신을 위해 트릭을 할해야

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

바로보기. –

+1

Genius, 많은 시간을 절약했습니다! –

+1

테스트하지는 않았지만 UIWebview의 기본 스크롤을 무시할 것이라고 생각합니다. 이게 맞지 않아? –

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 

는 대신,이는 네 슬쩍 방향을 처리하기 위해 하나의 제스처를 필요로

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

참고 수신 된 제스처의 방향을 감지하여 동작

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

설정 방향 당 하나의 UISwipeGestureRecognizer.

관련 문제