Cocoa touch 截取UIWebView中未使用的tap事件

Cocoa touch 截取UIWebView中未使用的tap事件,cocoa-touch,ipad,ios,uiwebview,touch,Cocoa Touch,Ipad,Ios,Uiwebview,Touch,我正在开发一款基于UIWebView的iPad应用程序:为了尽可能简单地解释它,该应用程序显示了一个大的交互式网络视图,此外还支持自定义手势 我需要捕获表示webview上单个点击的事件,但仅当点击尚未被webview使用时(即,它们不是滚动/缩放操作的开始,它们不是链接上的点击,它们不是触发某些javascript的点击) UIWebView对它的事件非常贪婪,根据我的经验,它倾向于不传播它们,即使它们没有被消费。为了捕获事件,我最终对主UIWindow进行了子类化(请参阅)。这工作得很好,但

我正在开发一款基于UIWebView的iPad应用程序:为了尽可能简单地解释它,该应用程序显示了一个大的交互式网络视图,此外还支持自定义手势

我需要捕获表示webview上单个点击的事件,但仅当点击尚未被webview使用时(即,它们不是滚动/缩放操作的开始,它们不是链接上的点击,它们不是触发某些javascript的点击)

UIWebView对它的事件非常贪婪,根据我的经验,它倾向于不传播它们,即使它们没有被消费。为了捕获事件,我最终对主UIWindow进行了子类化(请参阅)。这工作得很好,但问题是我无法识别我得到的点击是否触发了webview中的一些javascript

另外一个限制是,我无法控制将在UIWebView中运行的javascript或将要显示的HTML

因此,问题是这样的:什么样的方法可以检测所有且仅检测那些在UIWebView本身中没有触发任何其他操作的tap事件,特别是javascript操作

~


如果你好奇的话,我正在从事的项目的源代码是在GitHub上的:要找到它,只需让Google为你指出Baker Framework。

使用JavaScript完成这项工作。首先,在webview完成加载后,将javascript单击处理程序附加到主体上,以吸收任何未使用的单击。让它加载一个组成的域作为其操作:

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    NSString *script = @"document.body.onclick = function () { document.location.href = 'http://clickhandler'; }"
    [webView stringByEvaluatingJavaScriptFromString:script];
}
然后在您的webview委托中,查看是否有尝试加载组成域的内容并拦截它们。现在,您可以使用本机代码截取javascript单击处理程序并做出相应反应:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    if ([request.URL.host isEqualToString:@"clickhandler"])
    {
        //handle click
        //your logic here
        return NO;
    }
    return YES;
}

+1但我通常建议使用自定义方案,而不是使用假主机。因此,与其使用
http://clickhandler
,我建议
处理程序:
并使用
request.URL.scheme
检查它。这使得传递数据变得很容易,比如
handle:click
,它比伪主机更明确。我原本也这么认为,但这不是一个好主意。除非您将自定义方案作为受支持的方案添加到info.plist中,然后如果有人在Safari中键入该方案,它将启动您的应用程序,这是应用程序内部协议的意外副作用。将http://与没有顶级域(即最后没有.com)的假主机一起使用是安全的,因为它不可能与真实域发生冲突。我一直都这样做。您不需要注册自定义方案就可以在webview委托中捕获它。如果你想让其他应用程序转发给你,你只需要注册它。我很确定WebView以前不会正确处理自定义方案,除非应用程序正确声明它们,但可能不再是这样。试试吧。正如我所说,我已经用这种方式做了很长一段时间,我目前的项目非常依赖它。这里有一篇博文详细介绍了这一点: