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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28631317/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 04:55:49  来源:igfitidea点击:

How to disable scrolling entirely in a WKWebView?

ioswebview

提问by apouche

I know this looks like a simple question one can simply say:

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

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

or even

甚至

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

but while it does prevent scolling (in the contentOffsetmeaning) inside the WKWebviewit doesn'tprevent it from receiving pan gesture events involving scrolling.

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

So articles like those of the Huffington Post, which have javascript included to automatically change articles when the user scrolls left or right still get that behavior.

所以像赫芬顿邮报这样的文章,其中包含 javascript 以在用户向左或向右滚动时自动更改文章仍然会出现这种行为。

How can I prevent this ?

我怎样才能防止这种情况?

回答by Borut Tomazin

Before Swift 3

在 Swift 3 之前

You can simply disable scroll on its implicit scrollView

您可以简单地在其隐式 scrollView 上禁用滚动

webView.scrollView.scrollEnabled = false

Swift 3

斯威夫特 3

webView.scrollView.isScrollEnabled = false

回答by apouche

Took me a while but I figured out a way of doing this.

我花了一段时间,但我想出了一种方法来做到这一点。

I had to remove a private gesture recognizer within a private subview of the WKWebView.

我不得不在WKWebView.

I had a category on WKWebViewto do so:

我有一个类别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

Hope this helps anyone some day.

希望有一天这可以帮助任何人。

回答by Alain Stulz

Credit and many thanks to apouche for the Obj-C code. In case anybody else has the same problem, here is the working solution adapted for Swift 2

感谢 apouche 提供 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)
                }
            }
        }
    }
  }
}

回答by user5694405

finally self.webView.scrollView.userInteractionEnabled = NO

最后 self.webView.scrollView.userInteractionEnabled = NO

回答by user747594

I found that I had to make my view controller a UIScrollViewDelegatethen add this function to prevent scrolling.

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

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

回答by Tarostar

Here is a C# extension for WKWebView based on alain.s's swift solution (based on apouche's solution) for those of us using Xamarin. I am using this in my app.

这是 WKWebView 的 C# 扩展,基于 alain.s 的 swift 解决方案(基于apouche 的解决方案),适用于我们这些使用 Xamarin 的人。我在我的应用程序中使用它。

Notable differences is that I check if subviews exist before looping and instead of dynamically looking for a "WKContentView" (something I'm not sure is even possible in Xamarin) I simply check if each subview has GestureRecognizers and remove them. This will obviously disable all types of gestures so consider this if you expect any user interaction with the web content.

显着的区别是,我在循环之前检查子视图是否存在,而不是动态查找“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);
                                }
                            }
                        }
                    }


                }
            }
        }
    }

回答by Joey

Swift 5

斯威夫特 5

disableScrollView(self.webView)

func disableScrollView(_ view: UIView) {
    (view as? UIScrollView)?.isScrollEnabled = false
    view.subviews.forEach { disableScrollView(
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)
                    }
                }
            }
        }
    }
}
) } }

回答by Alan Jay

Here is a Swift 3 version:

这是一个 Swift 3 版本:

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)
                        }
                    }
                }
            }
        }

回答by Saul Hamadani

Here's a swift version if anyone's still having trouble with this issue

如果有人仍然遇到此问题,这是一个快速版本

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

回答by 3CC

Try to disable scrollView zoom in this way:

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

##代码##