UIWebView -- load external website, programmatically set initial zoom scale, and allow user to zoom afterwards
Asked Answered
I

5

14

Is it possible to do all of the above? SO has given me a great way to set the initial zoom scale here. Namely, to include the following line in my webViewDidFinishLoad method:

[webView stringByEvaluatingJavaScriptFromString: @"document.body.style.zoom = 5.0;"];

But what I still can't do is allow the user to change the zoom scale after the program initially sets it. If I set scalePagesToFit to NO, the user can't change the zoom scale. And if I set scalePagesToFit to YES, it overrides my programmatic zoom.

Can anyone help?

EDIT: thanks for the response. But if I zoom the scrollView, things blur a little.

Interrelate answered 8/11, 2011 at 1:0 Comment(0)
S
40

You can add or modify a <meta name='viewport' tag to achieve this. Apple documentation on the meta/viewport tag here:

https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html

Here's an example of adding the tag once the document is loaded:

- (void) webViewDidFinishLoad:(UIWebView *)webView
{
    NSString* js = 
    @"var meta = document.createElement('meta'); " \
     "meta.setAttribute( 'name', 'viewport' ); " \
     "meta.setAttribute( 'content', 'width = device-width, initial-scale = 5.0, user-scalable = yes' ); " \
     "document.getElementsByTagName('head')[0].appendChild(meta)";

    [webView stringByEvaluatingJavaScriptFromString: js];        
}

If the web page you're loading provides an existing meta tag you may need to modify it rather than attempting to add a new meta element to the DOM. This SO question discusses the technique:

Can I change the viewport meta tag in mobile safari on the fly?

In my test app I set the UIWebView scalesPageToFit to YES.

Scrivner answered 15/11, 2011 at 22:2 Comment(2)
Should also clear viewport before re-setting attributes: [webView stringByEvaluatingJavaScriptFromString: @"$('meta[name=viewport]').remove();"];Hatteras
Just chipping in with that fact that you don't need the backward slash ( \ ) when spanning the JS string over multiple lines. Only requirement is to open and close each new sentence with citation marks ( " ).Haleakala
L
3

It looks like the underlying UIScrollView is accessible starting from iOS 5.x.

In webViewDidFinishLoad: you can request a zoom, for example:

[webView.scrollView zoomToRect:CGRectMake(0.0, 0.0, 50.0, 50.0) animated:YES];

This seems to work even with scalesPageToFit set to YES.

Lefty answered 8/11, 2011 at 1:33 Comment(0)
K
3

This is actually brilliant. I needed to have zoom capability while scalePagesToFit is NO. Although your code TomSwift did not work as I needed, a slight adjustment to it did the trick.

I am running this on iOS 6.x...works like a charm.

NSString* js =
        @"var meta = document.createElement('meta'); " \
        "meta.setAttribute( 'name', 'viewport' ); " \
        "meta.setAttribute( 'content', 'width = device-width, initial-scale=1.0, minimum-scale=0.2, maximum-scale=5.0; user-scalable=1;' ); " \
        "document.getElementsByTagName('head')[0].appendChild(meta)";

[webView stringByEvaluatingJavaScriptFromString: js]; 

Awesome tip Tom.

Kolk answered 31/5, 2013 at 9:57 Comment(0)
S
0

Try changing the order that you are setting these commands - first scalePagesToFit to YES and then:

[webView stringByEvaluatingJavaScriptFromString: @"document.body.style.zoom = 5.0;"];
Scrim answered 15/11, 2011 at 14:38 Comment(0)
H
0

The difference with my answer is you are clearing the viewport before setting the width.

This allows for the web view to be rotated or resized (after being loaded) without resetting your attribute changes.

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    // Clear view port
    NSString* js = @"$('meta[name=viewport]').remove();";
    [webView stringByEvaluatingJavaScriptFromString: js];

    // Set content size
    js = [NSString stringWithFormat:@"var meta = document.createElement('meta');"
          "meta.setAttribute( 'name', 'viewport' ); "
          "meta.setAttribute( 'content', 'width = device-width, initial-scale = 5.0, user-scalable = yes' ); "
          "document.getElementsByTagName('head')[0].appendChild(meta);"];

    [webView stringByEvaluatingJavaScriptFromString: js];
}
Hatteras answered 9/11, 2015 at 6:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.