如何在WKWebView中完全禁用滚动?

时间:2015-02-20 14:28:39

标签: ios webview

我知道这看起来像一个简单的问题,可以简单地说:

webview.scrollView.scrollEnabled = NO;
webview.scrollView.panGestureRecognizer.enabled = NO;
webview.scrollView.bounces = NO;

甚至

for (UIView* subview in webview.subviews) {
  if ([subview respondsToSelector:@selector(setScrollEnabled:)]) {
      [(id)subview setScrollEnabled:enabled];
  }

  if ([subview respondsToSelector:@selector(panGestureRecognizer)]) {
      [[(id)subview panGestureRecognizer] setEnabled:enabled];
  }
}

虽然它确实阻止了contentOffset内部的WKWebview意义),但是不会阻止它接收涉及滚动的平移手势事件。

所以像Huffington Post这样的文章,当用户向左或向右滚动时,包含javascript以自动更改文章仍然会得到这种行为。

我该如何防止这种情况?

10 个答案:

答案 0 :(得分:31)

在Swift 3之前

您只需在其隐式scrollView

上禁用滚动即可
webView.scrollView.scrollEnabled = false

Swift 3

webView.scrollView.isScrollEnabled = false

答案 1 :(得分:6)

我花了一段时间,但我想出了一种方法。

我必须在WKWebView的私有子视图中删除私人手势识别器。

我在WKWebView上有一个类别:

@implementation WKWebView (Scrolling)

- (void)setScrollEnabled:(BOOL)enabled {
    self.scrollView.scrollEnabled = enabled;
    self.scrollView.panGestureRecognizer.enabled = enabled;
    self.scrollView.bounces = enabled;

    // There is one subview as of iOS 8.1 of class WKScrollView
    for (UIView* subview in self.subviews) {
        if ([subview respondsToSelector:@selector(setScrollEnabled:)]) {
            [(id)subview setScrollEnabled:enabled];
        }

        if ([subview respondsToSelector:@selector(setBounces:)]) {
            [(id)subview setBounces:enabled];
        }

        if ([subview respondsToSelector:@selector(panGestureRecognizer)]) {
            [[(id)subview panGestureRecognizer] setEnabled:enabled];
        }

        // here comes the tricky part, desabling
        for (UIView* subScrollView in subview.subviews) {
            if ([subScrollView isKindOfClass:NSClassFromString(@"WKContentView")]) {
                for (id gesture in [subScrollView gestureRecognizers]) {
                    if ([gesture isKindOfClass:NSClassFromString(@"UIWebTouchEventsGestureRecognizer")])
                        [subScrollView removeGestureRecognizer:gesture];
                }
            }
        }
    }

}


@end

希望有一天能帮到任何人。

答案 2 :(得分:5)

非常感谢Obj-C代码。如果其他人有同样的问题,这里是适用于Swift 2的工作解决方案

extension WKWebView {

  func setScrollEnabled(enabled: Bool) {
    self.scrollView.scrollEnabled = enabled
    self.scrollView.panGestureRecognizer.enabled = enabled
    self.scrollView.bounces = enabled

    for subview in self.subviews {
        if let subview = subview as? UIScrollView {
            subview.scrollEnabled = enabled
            subview.bounces = enabled
            subview.panGestureRecognizer.enabled = enabled
        }

        for subScrollView in subview.subviews {
            if subScrollView.dynamicType == NSClassFromString("WKContentView")! {
                for gesture in subScrollView.gestureRecognizers! {
                    subScrollView.removeGestureRecognizer(gesture)
                }
            }
        }
    }
  }
}

答案 3 :(得分:1)

我发现我必须让我的视图控制器为UIScrollViewDelegate,然后添加此功能以防止滚动。

func scrollViewDidScroll(_ scrollView: UIScrollView) {
   scrollView.setContentOffset(CGPoint(x: 0, y: 0), animated: false)
}

答案 4 :(得分:1)

这是WaWebView的C#扩展,它基于alain.s的快速解决方案(基于apouche的解决方案),适用于我们使用Xamarin的用户。我正在我的应用程序中使用它。

显着的区别是,我在循环之前检查子视图是否存在,而不是动态地寻找“ WKContentView”(我不确定在Xamarin中甚至可能做到这一点),我只是检查每个子视图是否具有GestureRecognizers并将其删除。显然,这将禁用所有类型的手势,因此,如果您希望用户与Web内容进行任何交互,请考虑使用此方法。

public static class WKWebViewExtension
    {
        public static void DisableScroll(this WebKit.WKWebView webView)
        {
            webView.ScrollView.ScrollEnabled = false;
            webView.ScrollView.PanGestureRecognizer.Enabled = false;
            webView.ScrollView.Bounces = false;

            if (webView.Subviews != null)
            {
                foreach (var subView in webView.Subviews)
                {
                    if (subView is UIScrollView)
                    {
                        UIScrollView subScrollView = (UIScrollView)subView;

                        subScrollView.ScrollEnabled = false;
                        subScrollView.Bounces = false;
                        subScrollView.PanGestureRecognizer.Enabled = false;
                    }

                    if (subView.Subviews != null)
                    {
                        foreach (var subScrollView in subView.Subviews)
                        {
                            if (subScrollView.GestureRecognizers != null)
                            {
                                foreach (var gesture in subScrollView.GestureRecognizers)
                                {
                                    subScrollView.RemoveGestureRecognizer(gesture);
                                }
                            }
                        }
                    }


                }
            }
        }
    }

答案 5 :(得分:0)

如果任何人仍然遇到此问题的麻烦,这是一个快速版本

let subviews = self.theWebView.scrollView.subviews
   for subview in subviews{
      if(subview.isKindOfClass(NSClassFromString("WKContentView"))){
                if let recognizers = subview.gestureRecognizers {
                    for recognizer in recognizers! {
                        if recognizer.isKindOfClass(NSClassFromString("UIWebTouchEventsGestureRecognizer")){
                           subview.removeGestureRecognizer(recognizer as! UIGestureRecognizer)
                        }
                    }
                }
            }
        }

答案 6 :(得分:0)

最后 self.webView.scrollView.userInteractionEnabled = NO

答案 7 :(得分:0)

这是一个Swift 3版本:

extension WKWebView {

    func setScrollEnabled(enabled: Bool) {
        self.scrollView.isScrollEnabled = enabled
        self.scrollView.panGestureRecognizer.isEnabled = enabled
        self.scrollView.bounces = enabled

        for subview in self.subviews {
            if let subview = subview as? UIScrollView {
                subview.isScrollEnabled = enabled
                subview.bounces = enabled
                subview.panGestureRecognizer.isEnabled = enabled
            }

            for subScrollView in subview.subviews {
                if type(of: subScrollView) == NSClassFromString("WKContentView")! {
                    for gesture in subScrollView.gestureRecognizers! {
                        subScrollView.removeGestureRecognizer(gesture)
                    }
                }
            }
        }
    }
}

答案 8 :(得分:0)

雨燕5

disableScrollView(self.webView)

func disableScrollView(_ view: UIView) {
    (view as? UIScrollView)?.isScrollEnabled = false
    view.subviews.forEach { disableScrollView($0) }
}

答案 9 :(得分:-1)

尝试以这种方式禁用scrollView缩放:

CGFloat zoomScale = webview.scrollView.zoomScale;
webview.scrollView.maximumZoomScale = zoomScale;
webview.scrollView.minimumZoomScale = zoomScale;