Disable magnification gesture in WKWebView
You can prevent your users from zooming by setting the delegate of your WKWebKit's UIScrollView and implementing viewForZooming(in:)
as in the following:
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 }}
I have tried setting minimumZoomScale
and maximumZoomScale
properties of UIScrollView
to 1
or isMultipleTouchEnabled
property of UIView
to false
or returning nil
from invoking viewForZooming(in:)
of UIScrollViewDelegate
but none worked. In my case, after several trial and error, the following works in my case [Tested on 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 }}
The below answer no longer works in iOS 10 beta.
To improve accessibility on websites in Safari, users can nowpinch-to-zoom even when a website sets user-scalable=no in theviewport.
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.
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, minimum-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.