Disabling callouts in WKWebView

A few months back I wrote about disabling the ability of a user to zoom a web page presented in a WKWebView. This is custom HTML content being displayed in an enterprise app, not a web site, so its not as nefarious as it sounds.

Another wish was to disable callouts. That's the pop-over that shows up when you long-tap on elements in Mobile Safari. They let you copy text, define a word or share a snippet.

A callout on iPad

A callout on iPad

There's no property on WKWebView that lets us do this, but we can do this similar to how we disabled the ability to zoom the page.

We pass a custom WKUserScript to our web view which creates a style tag and adds some styling which sets both -webkit-user-select and -webkit-touch-callout to none on all elements except input fields and textarea elements.

// 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 style = document.createElement('style'); \
    style.type = 'text/css'; \
    style.innerText = '*:not(input):not(textarea) { -webkit-user-select: none; -webkit-touch-callout: none; }'; \
    var head = document.getElementsByTagName('head')[0];\
    head.appendChild(style);";
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"]]];

As always, remember that these powers should only be used for good.