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