Swift 禁用WKWebView上的双击滚动

Swift 禁用WKWebView上的双击滚动,swift,scroll,double-click,wkwebview,wkwebviewconfiguration,Swift,Scroll,Double Click,Wkwebview,Wkwebviewconfiguration,我有一个自定义键盘,带有全宽和全高的WKWebView。我已通过wkWebView!禁用了滚动!。scrollView.scrollEnabled=false但双击WKWebView底部时,我仍然有一个奇怪的滚动行为。这里是我尝试加载的简单网页的源代码:(非常简单,只有一个div全屏背景绿色和一行文本)。下面,一个GIF作为解释。以下是我创建WKWebView的方式: class KeyboardViewController: UIInputViewController, WKScriptMes

我有一个自定义键盘,带有全宽和全高的WKWebView。我已通过
wkWebView!禁用了滚动!。scrollView.scrollEnabled=false
但双击WKWebView底部时,我仍然有一个奇怪的滚动行为。这里是我尝试加载的简单网页的源代码:(非常简单,只有一个div全屏背景绿色和一行文本)。下面,一个GIF作为解释。以下是我创建WKWebView的方式:

class KeyboardViewController: UIInputViewController, WKScriptMessageHandler {
var wkWebView: WKWebView?

override func loadView() {
    super.loadView()

    let contentController = WKUserContentController()
    contentController.addScriptMessageHandler(self, name:"callbackTestOne")

    let config = WKWebViewConfiguration()
    config.userContentController = contentController

    self.wkWebView = WKWebView(frame:self.view.frame, configuration:config)
    self.view = self.wkWebView!
}

override func viewDidLoad() {
    super.viewDidLoad()

    (...)

    wkWebView!.scrollView.bounces = false
    wkWebView!.scrollView.scrollEnabled = false
    wkWebView!.scrollView.backgroundColor = UIColor(red:248, green:248, blue:248, alpha:1)
    wkWebView!.scrollView.opaque = true
    wkWebView!.scrollView.showsHorizontalScrollIndicator = false
    wkWebView!.scrollView.showsVerticalScrollIndicator = false
    wkWebView!.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal
}

(...)

假设您可以控制在该
WKWebView
中显示的内容,则应为其设置正确的视口。这很可能会使这种行为失效

那么:

<meta id="viewport" name="viewport"
    content="width=device-width; user-scalable=false" />

肮脏的解决方案。但至少它起作用了。只需将您自己的UICapgestureRecognitor添加到包含WKWebView的视图中,并使您的UIViewController委托到此手势识别器。我使用了以下代码:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    if ([[otherGestureRecognizer description] containsString:@"WKSyntheticClickTapGestureRecognizer"] && [[otherGestureRecognizer description] containsString:@"numberOfTapsRequired = 2"]) {
        [otherGestureRecognizer removeTarget:nil action:nil];
        return YES;
    }
更新1 经过一些调查,我发现这种方法不太好。因为我们对长按菜单有问题,尤其是取消选择所选文本。还有一个问题对我来说——当菜单出现时,轻轻地向左或向右滑动——有时候WKWebView会开始滚动。
下一种方法是为WKWebViewConfiguration设置WKSelectionGranularityCharacter——我必须说这并不明显(苹果为什么要这样做?),所以它在iOS8上运行良好——没有双击,每个手势都能正常工作。然而对于iOS9,我们有个坏消息——它坏了。所以继续调查。

我也遇到了类似的问题,并找到了解决方案。也就是说,删除对错误行为负责的UITapgestureRecognitor

WKWebView,或者更准确地说,WKWebView中包含的UIScrollView及其子视图添加了许多手势识别器。因此,您可以轻松地迭代视图中的所有识别器,并删除所需的识别器

如果要从webView中删除所有单指双击识别器,则需要在滚动视图的子视图中进行搜索。您可以执行以下操作:

// iterate over all subviews of the WKWebView's scrollView
for subview in _webView.scrollView.subviews {

    // iterate over recognizers of subview
    for recognizer in subview.gestureRecognizers ?? [] {

        // check the recognizer is  a UITapGestureRecognizer
        if recognizer.isKind(of: UITapGestureRecognizer.self) {

            // cast the UIGestureRecognizer as UITapGestureRecognizer
            let tapRecognizer = recognizer as! UITapGestureRecognizer

            // check if it is a 1-finger double-tap
            if tapRecognizer.numberOfTapsRequired == 2 && tapRecognizer.numberOfTouchesRequired == 1 {

                // remove the recognizer
                subview.removeGestureRecognizer(recognizer)
            }
        }
    }
}

这应该可以解决您的问题。

这是用Swift 4.2编写的重构版只需将WKWebView作为参数传递,并调用viewDidLoad之类的函数

private func deleteDoubleTap(web: WKWebView) {
    for subview in web.scrollView.subviews {            
        let recognizers = subview.gestureRecognizers?.filter{$0 is UITapGestureRecognizer}
        recognizers?.forEach{recognizer in
            let tapRecognizer = recognizer as! UITapGestureRecognizer
            if tapRecognizer.numberOfTapsRequired == 2 && tapRecognizer.numberOfTouchesRequired == 1 {
                subview.removeGestureRecognizer(recognizer)
            }
        }
    }

}
与那里的想法相同,但更现代一点

func-webView(webView:WKWebView,didfish-navigation:WKNavigation!){
webView.scrollView.subviews.forEach{中的子视图
子视图.gestureRecograiners?.forEach{Recograiner中的
如果让tapRecognizer=识别器为UITapGestureRecognizer,
tapRecognizer.numberOfTapsRequired==2&&tapRecognizer.numberOfTouchesRequired==1{
子视图.RemovegestureRecognitor(识别器)
}
}
}
}

问题仍未解决。。。我发现了一个不好的解决方法:在本地加载的页面中,当滚动位置>0时,我使用jQuery自动滚动到顶部。代码:$(窗口).scroll(函数(){if($(窗口).scrollTop()>0){$(窗口).scrollTop(0);};})这是一个真正的问题。将WKWebView添加到iMessage应用程序或扩展时也会发生同样的情况。是的,我尝试使用此视口。但仍然存在这个滚动问题:sNice解释!适用于我的案例-只允许一次点击。谢谢这种方法适用于web视图的初始渲染。但是,在您按住鼠标缩放网页后,双击的手势又回来了。我还没有找到根本原因。应该在完成导航后调用它,否则将不起作用