ios 在 WKWebView 中禁用放大手势

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25553711/
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 02:05:59  来源:igfitidea点击:

Disable magnification gesture in WKWebView

ioswebkitios8wkwebview

提问by Kevin

I'm looking for a way to disable the "pinch to zoom" magnification gesture on the iOS implementation of WKWebView. There is a magnification BOOL property available for OS X but it doesn't seem to be available on iOS.

我正在寻找一种在 WKWebView 的 iOS 实现上禁用“捏合缩放”放大手势的方法。有一个可用于 OS X 的放大 BOOL 属性,但它似乎不适用于 iOS。

WKWebView.h

WKWebView.h

#if !TARGET_OS_IPHONE
/* @abstract A Boolean value indicating whether magnify gestures will
 change the web view's magnification.
 @discussion It is possible to set the magnification property even if
 allowsMagnification is set to NO.
 The default value is NO.
 */
@property (nonatomic) BOOL allowsMagnification;

I've, also, tried look at the WKWebView's gesture recognizers but that seems to be turning up an empty array. I'm assuming the actual recognizers are bured deeper in the component's structure (fairly complex, by the looks of it) and would rather not go digging for them if at all possible.

我也试过查看 WKWebView 的手势识别器,但这似乎变成了一个空数组。我假设实际的识别器在组件的结构中更深(从它的外观来看相当复杂),并且如果可能的话宁愿不去挖掘它们。

I know of possible hacks that could potentially disable the gesture from firing (selectively passing gestures to the WebView, add child view to capture pinch gesture, etc) but I've always found those introduce lag into the event and want to keep the implementation as clean/hack free as possible.

我知道可能的黑客攻击可能会禁用手势触发(有选择地将手势传递给 WebView,添加子视图以捕获捏合手势等),但我总是发现那些会在事件中引入延迟并希望保持实现为尽可能干净/无黑客。

回答by Landschaft

You can prevent your users from zooming by setting the delegate of your WKWebKit's UIScrollView and implementing viewForZooming(in:)as in the following:

您可以通过设置 WKWebKit 的 UIScrollView 的委托并按viewForZooming(in:)如下方式实现来防止用户缩放:

class MyClass {
    let webView = WKWebView()

    init() {
        super.init()
        webView.scrollView.delegate = self
    }

    deinit() {
        // Without this, it'll crash when your MyClass instance is deinit'd
        webView.scrollView.delegate = nil
    }
}

extension MyClass: UIScrollViewDelegate {
    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        return nil
    }
}

回答by Kevin

The below answer no longer works in iOS 10 beta.

以下答案不再适用于 iOS 10 测试版。

To improve accessibility on websites in Safari, users can now pinch-to-zoom even when a website sets user-scalable=no in the viewport.

为了提高 Safari 中网站的可访问性,即使网站在视口中设置了 user-scalable=no,用户现在也可以捏合缩放。



WKWebView seems to respect the viewport meta tag the same way Mobile Safari does (as to be expected). So, I found injecting that tag into the DOM through javascript after a page load does the trick. I would be weary of this solution unless you know exactly what HTML is being loaded into the webview, otherwise I suspect it would have unintended consequences. In my case, I'm loading HTML strings, so I can just add it to the HTML I ship with the app.

WKWebView 似乎以与 Mobile Safari 相同的方式尊重视口元标记(正如预期的那样)。所以,我发现在页面加载后通过 javascript 将该标签注入到 DOM 中。我会厌倦这个解决方案,除非你确切地知道什么 HTML 正在加载到 webview 中,否则我怀疑它会产生意想不到的后果。就我而言,我正在加载 HTML 字符串,因此我可以将其添加到应用程序随附的 HTML 中。

To do it generically for any webpage:

要对任何网页进行一般性操作:

- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
    NSString *javascript = @"var meta = document.createElement('meta');meta.setAttribute('name', 'viewport');meta.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no');document.getElementsByTagName('head')[0].appendChild(meta);";

    [webView evaluateJavaScript:javascript completionHandler:nil];
}

It might be wise to take a look at what kind of navigation has just been completed, since only a new page will need this javascript executed.

看看刚刚完成的导航类型可能是明智的,因为只有新页面需要执行此 javascript。

回答by yohannes

I have tried setting minimumZoomScaleand maximumZoomScaleproperties of UIScrollViewto 1or isMultipleTouchEnabledproperty of UIViewto falseor returning nilfrom invoking viewForZooming(in:)of UIScrollViewDelegatebut none worked. In my case, after several trial and error, the following works in my case [Tested on iOS 10.3]:

我曾尝试设置minimumZoomScalemaximumZoomScale属性UIScrollView1isMultipleTouchEnabled财产UIViewfalse或返回nil援引viewForZooming(in:)UIScrollViewDelegate,但没有奏效。就我而言,经过多次反复试验,以下在我的情况下有效[在 iOS 10.3 上测试]:

class MyViewController: UIViewController {
   var webView: WKWebView?

   override viewDidLoad() {
      super.viewDidLoad()

      //...
      self.webView.scrollView.delegate = self
      //...
   }
}

extension MyViewController: UIScrollViewDelegate { 
   func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
      scrollView.pinchGestureRecognizer?.isEnabled = false
   }
}

回答by pulse4life

The native solutions were not working for me, and injecting JS is not ideal. I noticed that when a zoom occurs and my delegate is called, the pinchGestureRecognizer is enabled even though I disabled it when initializing the webview. To fix this, I set it to disabled whenever a zoom starts:

本机解决方案对我不起作用,注入 JS 并不理想。我注意到当发生缩放并调用我的委托时,即使我在初始化 webview 时禁用了 pinchGestureRecognizer,它也会启用。为了解决这个问题,我在缩放开始时将其设置为禁用:

extension ViewController: UIScrollViewDelegate {

    // disable zooming in webview
    func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
        scrollView.pinchGestureRecognizer?.isEnabled = false
    }
}

回答by Gulshan Kumar

Complete working code to disable zooming in WkWebView in Swift.

在 Swift 中禁用 WkWebView 缩放的完整工作代码。

import UIKit
import WebKit

class ViewController: UIViewController, WKUIDelegate {
    var webView : WKWebView!

    override func loadView() {
        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration:webConfiguration)
        webView.uiDelegate = self

        let source: String = "var meta = document.createElement('meta');" +
            "meta.name = 'viewport';" +
            "meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no';" +
            "var head = document.getElementsByTagName('head')[0];" + "head.appendChild(meta);";

        let script: WKUserScript = WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
        webView.configuration.userContentController.addUserScript(script)

        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let myUrl = URL(string: "https://www.google.com")

        let myRequest = URLRequest(url: myUrl!)
        webView.load(myRequest)
    }
}

回答by Simon Epskamp

Full Swift 3 / iOS 10version of Landschaft's answer:

Landschaft 的完整Swift 3 / iOS 10版本的答案:

import UIKit
import WebKit

class MyViewController: UIViewController, UIScrollViewDelegate {

    var webView = WKWebView()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(webView)
        webView.scrollView.delegate = self
    }

    // Disable zooming in webView
    func viewForZooming(in: UIScrollView) -> UIView? {
        return nil
    }
}

回答by Yakup Ad

You can use UIScrollViewDelegate for this. First assign delegate to your webview in viewDidLoad() or any other suitable method as:

您可以为此使用 UIScrollViewDelegate。首先在 viewDidLoad() 或任何其他合适的方法中将委托分配给您的 webview:

class LoginViewController: UIViewController, WKUIDelegate, UIScrollViewDelegate {

  override func viewDidLoad() {
      webView.scrollView.delegate = self 
  }

  //Add this delegate method in your view controller
  func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
      scrollView.pinchGestureRecognizer?.isEnabled = false
  }
}

回答by Leszek Szary

In case you display a local html you could just modify this html and put this meta tag to your html:

如果您显示本地 html,您只需修改此 html 并将此元标记放入您的 html:

<head>
<meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0' name='viewport' />
</head>

回答by quemeful

Swift 2.0

斯威夫特 2.0

extension WKWebView {
    func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
        return nil
    }
}

回答by godblessstrawberry

this is how I disabled zoom for Swift3view controller for one-webview-only app

这就是我为一个 webview-only 应用程序禁用Swift3视图控制器缩放的方式

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, UIScrollViewDelegate {

    @IBOutlet var webView: WKWebView!

    override func loadView() {
        webView = WKWebView()
        webView.navigationDelegate = self
        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        webView.scrollView.delegate = self
    }

    func viewForZooming(in: UIScrollView) -> UIView? {
        return nil;
    }    

}