papafe
papafe

Reputation: 3070

Force HTML content to fit in device width with WkWebview

I have a WkWebview that is supposed to show the content of HTML emails. The issue is that sometimes the content is larger than the window, and so it requires the user to scroll in order to see the full email.

Is it possible to avoid this and have a similar behaviour as what happens with the default iOS mail app? In fact, in the Mail app, it seems that the content is fit, no matter the kind of email.

Upvotes: 5

Views: 8577

Answers (4)

Benjamin RD
Benjamin RD

Reputation: 12044

Similar to @nferocious76's but in Swift language

Swift

var scriptContent = "var meta = document.createElement('meta');"
scriptContent += "meta.name='viewport';"
scriptContent += "meta.content='width=device-width';"
scriptContent += "document.getElementsByTagName('head')[0].appendChild(meta);"

webView.evaluateJavaScript(scriptContent, completionHandler: nil)

Objective C

NSString *jScript = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";

WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
WKUserContentController *wkUController = [[WKUserContentController alloc] init];
[wkUController addUserScript:wkUScript];

WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];
wkWebConfig.userContentController = wkUController;

wkWebV = [[WKWebView alloc] initWithFrame:self.view.frame configuration:wkWebConfig];

Upvotes: 4

Frost
Frost

Reputation: 648

If you are OK with scaling the content, you can disable scrolling and disable mask autotranslation, and set an NSLayoutConstraint to make the content to fit the size you want.

The example below makes an 'oversized' html document scale to 80% of the screen width, using an aspect ratio of 1:1. It is vertically constrained to be located close to the bottom of the screen. Of course, replace the constraints with whatever size you need.

let configuration = WKWebViewConfiguration()
webView = WKWebView(frame: self.view.frame, configuration: configuration)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.scrollView.isScrollEnabled = false

let height = NSLayoutConstraint(item: self.webView, attribute: .height, relatedBy: .equal, toItem: self.view, attribute: .width, multiplier: 0.8, constant: 0)
let width = NSLayoutConstraint(item: self.webView, attribute: .width, relatedBy: .equal, toItem: self.view, attribute: .width, multiplier: 0.8, constant: 0)

let horizontalCenter = NSLayoutConstraint(item: self.webView, attribute: .centerX, relatedBy: .equal, toItem: self.view, attribute: .centerX, multiplier: 1.0, constant: 0.0)
let bottomOffset = self.webView.frame.size.width * 0.1
let bottomConstraint = NSLayoutConstraint(item: self.bottomLayoutGuide, attribute: .top, relatedBy: .equal, toItem: self.webView, attribute: .bottom, multiplier: 1.0, constant: bottomOffset)

self.view.addConstraints([height, width, horizontalCenter, bottomConstraint])

Upvotes: 0

Shawn Locke
Shawn Locke

Reputation: 1

    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    configuration.userContentController = [[WKUserContentController alloc] init];

    NSString *source = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";

    WKUserScript *script = [[WKUserScript alloc] initWithSource:source injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
    [configuration.userContentController addUserScript:script];

    self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];

Upvotes: 0

Arun K
Arun K

Reputation: 840

You can achieve this by adding this code after you webpage has loaded. That is in this function at the end func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)

let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
    let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
    let wkUController = WKUserContentController()
    wkUController.addUserScript(userScript)
    let wkWebConfig = WKWebViewConfiguration()
    wkWebConfig.userContentController = wkUController
    let yourWebView = WKWebView(frame: self.view.bounds, configuration: wkWebConfig)// yourwebview is the webview that you are using.

Upvotes: 2

Related Questions