UIGestureRecognizer是否在UIWebView上工作?

我试图得到一个UISestureRecognizer与一个UIScrollView的子视图的UIWebview。 这听起来很奇怪,但是当我将numberOfTouchesRequired设置为2时,select器会触发,但是当numberOfTouchesRequired设置为1时,select器不会触发。

这是我的代码:

 UITapGestureRecognizer *tap1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(select1:)]; tap1.numberOfTouchesRequired = 2; tap1.numberOfTapsRequired = 1; tap1.delegate = self; [self.ans1WebView addGestureRecognizer:tap1]; [tap1 release]; - (void) select1:(UILongPressGestureRecognizer *)sender { //Do Stuff } 

我已经证实了这一点,使用UIGestureRecognizer的苹果示例,并在他们的笔尖插入一个webview。 他们的抽头代码在任何地方工作,但在webview的区域内。

从我所看到的,UIWebView与其他人玩不好。 对于手势识别器,您可以尝试从以下位置返回YES:

 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer; 

我不得不向后兼容3.0,所以我最终做了UIWebView中的所有使用Javascript的手势处理。 不是一个好的解决scheme,但是它符合我的需求。 我能够捕捉一个元素的长按,以及点击,轻扫,捏和旋转。 当然,我只使用本地内容。

编辑:

您可以在PhoneGap中查看向UIWebView的委托发送消息的示例。 简而言之,您使用document.location = "myscheme:mycommand?myarguments"然后document.location = "myscheme:mycommand?myarguments"callback中parsing出命令和参数:

 -(BOOL) webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType { if ( [[[inRequest URL] absoluteString] hasPrefix:@"myscheme:"] ) { //.. parse arguments return NO; } } 

您可以在PhoneGap代码中看到他们设置了一个队列和定时器来发送消息。 根据您的使用情况,您可能需要做同样的事情。 关于这个话题还有其他的问题。

这是事件处理文档。 在我的情况下,我添加事件监听器从<body onload="myloader();"> document

 function myloader() { document.addEventListener( 'touchcancel' , touch_cancel , false ); document.addEventListener( 'touchstart' , touch_start , false ); document.addEventListener( 'touchmove' , touch_move , false ); document.addEventListener( 'touchend' , touch_end , false ); }; 

实际的事件处理很大程度上取决于您的需求。 每个事件处理程序将接收一个触摸属性的触摸事件,其中每个项目是一个触摸 。 你可以logging你的touchstart处理程序的开始时间和位置。 如果接触时间过长或错过了一段时间,则不是长时间接触。

WebKit可能会尝试处理长时间触摸以开始select和复制。 在你的事件处理程序中,你可以使用event.preventDefault(); 停止默认行为。 我还发现了-webkit-user-select:none一些css属性。

 var touch = {}; function touch_start( event /*TouchEvent*/ { event.preventDefault(); touch = {}; touch.startX = event.touches.item(0).pageX; touch.startY = event.touches.item(0).pageY; touch.startT = ( new Date() ).getTime(); } 

这只是我已经使用JavaScript的第二个项目。 你可以在别处find更好的例子。

正如你所看到的,这不是对你的问题的快速回答。 我很满意我得到的结果。 我正在使用的HTML没有链接或两个以上的交互式元素。

UIWebView有自己的私人视图,也有附加的手势识别器。 因此,优先规则保持添加到UIWebView的任何手势识别器无法正常工作。

一种select是实现UIGestureRecognizerDelegate协议并实现方法gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer。 对于其他轻敲手势,从此方法返回YES。 这样你就可以调用你的tap处理程序,web view仍然会被调用。

在Apple开发论坛上看到这个 。

这是一个有点黑客的解决scheme,但它的工作原理。 UIWebView有很多内部的手势识别器,通常你不能使用私有API访问。 你可以免费得到它们,不过,当你实现gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: 在这一点上,你可以告诉所有的内部UITapGestureRecognizer只有当你自己的UITapGestureRecognizer失败时才会触发。 你只做一次,然后从你自己的手势识别器中删除这个委托。 结果是,您仍然可以平移和滚动您的webView,但不会再收到任何(单一)轻敲手势。

 - (void)viewDidLoad { [super viewDidLoad]; UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)]; // view is your UIViewController's view that contains your UIWebView as a subview [self.view addGestureRecognizer:tap]; tap.delegate = self; } - (void)handleTapGesture:(UITapGestureRecognizer *)gestureRecognizer { NSLog(@"tap!"); // this is called after gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: so we can safely remove the delegate here if (gestureRecognizer.delegate) { NSLog(@"Removing delegate..."); gestureRecognizer.delegate = nil; } } - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { if ([otherGestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) { [otherGestureRecognizer requireGestureRecognizerToFail:gestureRecognizer]; NSLog(@"added failure requirement to: %@", otherGestureRecognizer); } return YES; } 

请享用!

我遇到了同样的问题。 这个解决scheme为我工作:

1)确保将协议添加到您的界面:UIGestureRecognizerDelegate例如:

 @interface ViewController : UIViewController <SlideViewProtocol, UIGestureRecognizerDelegate> 

2)添加这一行代码

 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES } 

3)设置手势

 UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(nextSlide)]; swipeGesture.numberOfTouchesRequired = 1; swipeGesture.direction = (UISwipeGestureRecognizerDirectionLeft); swipeGesture.cancelsTouchesInView = YES; [swipeGesture setDelegate:self]; [self.view addGestureRecognizer:swipeGesture]; 
 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer { return YES; } 

另一种方法是在UIWebView之上放置一个透明的UIButton,并处理这个button的点击。 在某些情况下,这可能是一个好的解决scheme。

 UIWebView webView = [UIWebView new]; //... UIButton *transparentButton = [UIButton buttonWithType:UIButtonTypeCustom]; [transparentButton addTarget:self action:@selector(buttonTapped) forControlEvents:(UIControlEventTouchUpInside)]; transparentButton.frame = webView.frame; transparentButton.layer.backgroundColor = [[UIColor clearColor] CGColor]; [self.view transparentButton]; 

您也可以在这里find我的答案有帮助。 这是一个在UIWebView的javascript中处理捏手势的工作示例。

(如果你愿意的话,你可以把事件传回给Objective-C,见我的答案 。)