2012-08-08 18 views
6

के अंदर जेस्चर रिकग्निशन स्वाइप करें मैंने इस पर प्रश्नों का एक समूह पढ़ा है, लेकिन उनमें से कोई भी जो मैं ढूंढ रहा हूं उसे प्राप्त करने के लिए प्रतीत होता है ... तो मान लें किके अंदर मुझे मनमानी UIWebView है। UIViewController में SwipeGestureRecognizer है जो ठीक काम करता है। यह UIWebView के भीतर भी काम करता है - जब भी कोई स्क्रॉलबार नहीं होता है। (इससे पहले कि मैं एक पृष्ठ लोड करता हूं या यहां तक ​​कि यदि मैं एक पृष्ठ लोड करता हूं जो मेरे UIWebView के आकार के भीतर उचित रूप से फिट हो सकता है)। हालांकि, अगर मैं एक वेबपृष्ठ लोड करता हूं जिसके लिए क्षैतिज स्क्रॉलिंग को बाएं या दाएं की आवश्यकता होती है, तो मेरे दृश्य के UIWebView भाग के अंदर, मुझे पहचानने के लिए कोई स्वाइप जेस्चर नहीं मिल सकता है। प्रत्येक क्लिक/ड्रैग/स्वाइप केवल स्क्रॉल एक्शन ट्रिगर करता है। क्या "स्वाइप" और बस अपनी उंगली के साथ स्क्रॉल करने का कोई तरीका है (इसे उठाना नहीं बल्कि स्क्रॉल करने के लिए खींच रहा है)।UIWebView

उत्तर

2

आपको UIWebView को उपclass करना होगा और इशारा पहचानकर्ता कॉल को ओवरराइड करना होगा।

संपादित करें - इस पोस्ट 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

हाँ को देखो, तो आप 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

बस ठीक काम करता है। –

+1

जीनियस, मेरे बहुत समय बचाया! –

+1

मैंने इसका परीक्षण नहीं किया है, लेकिन मुझे लगता है कि यह UIWebview की डिफ़ॉल्ट स्क्रॉलिंग को ओवरराइड करेगा। क्या यह सही नहीं है? –

1

Johannes Fahrenkrug's answer सशर्त रूप से वेब व्यू के अंतर्निर्मित पैन जेस्चर को अवरुद्ध करने में सफल रहा। हालांकि, मैंने पाया कि यह केवल तभी काम करता है जब वेबव्यू के पैन जेस्चर बहुत धीमे थे ... अगर मैंने किसी भी उचित गति के साथ वेब व्यू को पॅन किया है, तो स्वाइप इशारा ट्रिगर किया गया था। मैं डिफ़ॉल्ट वेबव्यू स्क्रॉलिंग कार्यक्षमता का उपयोग करने के लिए स्वाइप इशारा, और मध्यम या धीमी पैन को ट्रिगर करने के लिए केवल एक तेज़ स्वाइप चाहता था।

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।