On a current project we're using the newly introduced (in iOS 8) and mostly awesome
WKWebView
to show custom HTML content. Now for some very specific reasons I can't get into, we need to
disable the pinch-to-zoom gesture for all the pages that are displayed.
Luckily WKWebView has an allowsMagnification property to do just this, but unfortunately
this and the other properties that allow you to modify the magnification are only available
on OS X.
But all is not lost, we can attach our own custom Javascript to any page that we load. And
with a little help from Javascript we can create a meta tag that disables scaling of the
viewport and inject it into the document's <head>.
Once we have this Javascript we can create a WKUserScript object which we tell the
WKUserContentController to always inject into loaded pages, and pass that controller to a
WKWebViewConfiguration object, which is used when we create our WKWebView.
That sounds like a mouthful but its quite straightforward. Paste code the code below into a
UIViewController's viewDidLoad method to try it out.
UPDATE: Initially I had written that we were loading arbitrary content from around the web which wasn't strictly the case and also caused a few people to suggest that this was a bad thing. Absolutely 100% agree. However in this specific case we are loading custom content, produced in-house and requires the gesture to be disabled.
Otherwise you probably should never do this.
// Remember to @import WebKit at the top of the class
// Javascript that disables pinch-to-zoom by inserting the HTML viewport meta tag into <head>
NSString *source = @"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);";
WKUserScript *script = [[WKUserScript alloc] initWithSource:source injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
// Create the user content controller and add the script to it
WKUserContentController *userContentController = [WKUserContentController new];
[userContentController addUserScript:script];
// Create the configuration with the user content controller
WKWebViewConfiguration *configuration = [WKWebViewConfiguration new];
configuration.userContentController = userContentController;
// Create the web view with the configuration
WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
webView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:webView];
// Add the constraints
NSDictionary *views = NSDictionaryOfVariableBindings(webView);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[webView]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[webView]|" options:0 metrics:nil views:views]];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://apple.com"]]];
And the same thing in Swift for funsies:
// Remember to @import WebKit at the top of the class
// Javascript that disables pinch-to-zoom by inserting the HTML viewport meta tag into <head>
let source: NSString = "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)
// Create the user content controller and add the script to it
let userContentController: WKUserContentController = WKUserContentController()
userContentController.addUserScript(script)
// Create the configuration with the user content controller
let configuration: WKWebViewConfiguration = WKWebViewConfiguration()
configuration.userContentController = userContentController
// Create the web view with the configuration
let webView: WKWebView = WKWebView(frame: CGRectZero, configuration: configuration)
webView.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(webView)
// Add the constraints
let views: NSDictionary = ["webView" : webView]
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[webView]|", options: .AlignAllLeft, metrics: nil, views: views))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[webView]|", options: .AlignAllLeft, metrics: nil, views: views))
webView.loadRequest(NSURLRequest(URL: NSURL(string: "http://apple.com")!))