Disable zoom in WKWebView?

2020-02-10 07:16发布

问题:

Does anyone know a nice simple way to disable double-click and pinch zooming in a WKWebView? Nothing I've tried works:

Webview.scrollView.allowsMagnification = false;    // Error: value of type WKWebView has no member allowsMagnification

Webview.scrollView.isMultipleTouchEnabled = false; // doesn't do anything

In the html:

<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" /> // pile of crap, does nothing

回答1:

You will have to add maximum scale in script.

The following code should help you:

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)
let userContentController: WKUserContentController = WKUserContentController()
let conf = WKWebViewConfiguration()
conf.userContentController = userContentController
userContentController.addUserScript(script)
let webView = WKWebView(frame: CGRect.zero, configuration: conf)


回答2:

Swift 4:

@IBOutlet weak var webView: WKWebView!

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

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


回答3:

This post explain how managing the zoom.

WebKit: New Interaction Behaviors in iOS 10

In iOS 10 "ignoresViewportScaleLimits" property was added to WKWebViewConfiguration, which is false by default. The post recommends to set to true and to manage correctly the zoom in the page.

Note: In Safari and SafariViewController the value for this property is true by default.

In my case I want to reset the zoom in some cases. For this the unique way that I found it was change maximum scale to 1.0 and after to 10.0.

NSString* js =
    @"var meta = document.createElement('meta'); " \
    "meta.setAttribute( 'name', 'viewport' ); " \
    "meta.setAttribute( 'content', 'width = device-width, initial-scale = 1.0, minimum-scale = 1.0, maximum-scale = 1.0, user-scalable = yes' ); " \
    "document.getElementsByTagName('head')[0].appendChild(meta)";
[_wkWebview evaluateJavaScript:js completionHandler:^(id _Nullable object, NSError * _Nullable error) {
    NSString* js =
    @"var meta = document.createElement('meta'); " \
    "meta.setAttribute( 'name', 'viewport' ); " \
    "meta.setAttribute( 'content', 'width = device-width, initial-scale = 1.0, minimum-scale = 1.0, maximum-scale = 10.0, user-scalable = yes' ); " \
    "document.getElementsByTagName('head')[0].appendChild(meta)";
    [_wkWebview evaluateJavaScript:js completionHandler:nil];
}];

This code should works but I recommend to create the "viewport" always in the html and to create a function (i.e. resetZoom or disableZoom) in the javascript to call it directly from objective-C (it is cleaner)

I hope it helps.



回答4:

OK this is how I solved this:

wkWebView.configuration.userContentController.addUserScript(self.getZoomDisableScript()) 

private func getZoomDisableScript() -> WKUserScript {
    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);"
    return WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
}