使用UIWebView实现手势识别

11
我在构建的应用中设置了一些手势识别。其中一个手势是单指单击,可以隐藏屏幕顶部的工具栏。它运行得非常好,但有一个问题:点击链接也会使工具栏消失。
是否可能检测到不是链接的点击?我能否通过查看点击发生的位置,并只在它没有发生在HTML链接上时采取行动来实现这一点?如果可能的话,提供如何确定是否点击了链接的指针将很有帮助。
按照Octy的建议,我尝试将UIWebView包装在UIView中。我正在使用界面生成器,所以我在层次结构中插入了一个视图,并将UIWebView变为新UIView的"子级"。现在层次结构如下:

Hierarchy screen shot

我在视图控制器中添加了一个视图的IBOutlet,并在界面构建器中进行了链接。

我将手势识别器的设置更改为如下所示:

UITapGestureRecognizer* singleTap=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleSingleTap:)];
singleTap.numberOfTouchesRequired=1;
singleTap.delegate=self;
[self.UIWebViewContainer addGestureRecognizer:singleTap];
[singleTap release];

这段代码位于viewDidLoad中。
与之前一样,代码可以正确识别单指单击,但在UIWebView上点击链接也会导致工具栏消失。我只希望在未点击链接时工具栏消失。
有人有什么建议吗?
谢谢。
Chris
谢谢 Chris

编辑以添加有关如何实现的问题。 - Chris
在尝试@octy的建议后,编辑以添加额外信息。 - Chris
6个回答

10
尝试将您的UIWebView放入一个UIView容器中,并在容器视图上设置手势识别器。未经UIWebView处理的触摸事件将向上传递到视图层次结构并被容器视图拦截,假设它实现了适当的处理程序(而应该在这些处理程序中实现隐藏工具栏的代码...)。

你尝试在UIWebView上设置exclusiveTouch = YES了吗?不确定它是否有效,但我现在想不到其他有意义的解决方案了...抱歉!手势识别器的问题在于它们不参与事件传递链。因此,如果这不起作用,我们必须想出更复杂的解决方案。 - octy
是的。Exclusivetouch 也不起作用。我在想是否因为UIWebView在事件发生时不知道用户是否触摸了任何有意义的东西,所以它会捕获所有单指单击。 - Chris
1
@octy - 我和你一样遇到了同样的问题,然而,这个问题的答案并没有解决这个问题(正如你所说的)。你有找到解决方法吗? - 5StringRyan
但为什么这个答案被标记为正确并且得到了那么多赞?它真的对某些人有效吗?我这里没有用! - cprcrack
我遇到了同样的问题。添加“GESTURE.delegate = self”之后,它就可以工作了。对我来说,需要委托有点奇怪。 - Vinh
显示剩余4条评论

3

好的,一个“hack-ish”的解决方法是将包含UIWebView的视图控制器作为您实例化的手势识别器的委托(UIGestureRecognizerDelegate)。我通常不喜欢这样的解决方案,但是...

将手势识别器分配给包装Web视图的视图,并将其委托设置为self。

然后在委托方法gestureRecognizer:shouldRecieveTouch中,将状态设置为指示有一个点击事件,

从委托方法返回NO,以便事件沿着响应者链传播到UIWebView。

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{

    _userTapped = YES;
    [self performSelectorOnMainThread:@selector(hideMenuIfNotLink) afterDelay:??.?];
//??.?? amount of time to lapse to see if shouldStartLoadWithRequest gets called.
   return NO;

}

-(void)hideMenuIfNotLink{
    if(_userTapped)
         //hideMenu
}

现在,在您的UIWebViewDelegate中的shouldStartLoadWithRequest方法中(当用户实际上单击链接时调用此方法)。
if(_userTapped){
    _userTapped = NO;
     //possibly code to reshow or verify keep showing menu
}

1

是的,我正在做那个。也许我没有正确地提问。我想要达到的目标是:我想检测在 uiwebview 上的点击事件,但这些点击不是用于链接的。我想使用这些点击来隐藏工具栏。如果用户点击了链接,我不想隐藏工具栏。--谢谢 - Chris

1
我一直在寻找同样的东西,最终找到了这个:iOS有一个特定的属性,可以在您按住链接时禁用弹出窗口。您可以将其添加到链接的样式表(CSS)中。
-webkit-touch-callout: none;

1
这对我有用。尝试添加下面一行代码。
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}

0
我曾经遇到过同样的问题。这个解决方案对我有用:
1)确保在您的接口中添加协议:UIGestureRecognizerDelegate,例如:
@interface ViewController : UIViewController _SlideViewProtocol, UIGestureRecognizerDelegate_

2) 添加这行代码

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接