48

I have a webview which is the top window in the hierarchy and has been declared as shown below. However, it does not scale pages to fit. Pages are top left aligned, but are not scaled, despite the scalesPageToFit property being set to YES. Any help would be greatly appreciated.

webLookupView = [[UIWebView alloc] initWithFrame:CGRectMake(16, 63, 289, 327)];
webLookupView.backgroundColor = [UIColor lightGrayColor];
webLookupView.dataDetectorTypes = UIDataDetectorTypeAll;
webLookupView.scalesPageToFit = YES;
pkamb
  • 33,281
  • 23
  • 160
  • 191
RunLoop
  • 20,288
  • 21
  • 96
  • 151

12 Answers12

36

iOS5 gives a better solution

call this from webViewDidFinishLoad

- (void)zoomToFit
{ 
    if ([theWebView respondsToSelector:@selector(scrollView)])
    {
        UIScrollView *scrollView = [theWebView scrollView];

        float zoom = theWebView.bounds.size.width / scrollView.contentSize.width;
        scrollView.minimumZoomScale = zoom;
        [scrollView setZoomScale:zoom animated:YES];
    }
}
henkieee
  • 1,123
  • 1
  • 8
  • 10
Confused Vorlon
  • 9,659
  • 3
  • 46
  • 49
  • I tried it but it doesn't work for me. The method webViewDidFinishLoad is being invoked, but it doesn't influence the size – Dejell Dec 24 '12 at 15:07
  • Hi it works, be we have time to see original size, before the scale append. any way to get this done before? – Franck Apr 06 '13 at 19:30
  • You'll also need to validate manually zoom range! I think that's the key :) ```scroll.zoomScale = MIN(MAX(zoom, scroll.minimumZoomScale), scroll.maximumZoomScale)``` – rudyryk Oct 23 '13 at 18:25
  • 1
    worked, but "Scales pages to fit" on webview needs to be checked. – codrut Apr 29 '14 at 14:24
  • It does not work well for me as it seems the scrollview of the webview does not fix the contentsize. I can scroll to black areas... – Kasas Oct 23 '14 at 09:04
  • @confusedvorlon Awesome Answer.....scalestopages and content mode property didn't work for me but this did. device iPhone 4S, 5, 6, 6plus all having iOS 8.0+ – madLokesh Mar 12 '15 at 06:24
  • 2
    This is great, but right after it scales, it pops back to the previous size. Any ideas? – Alex Zavatone May 26 '16 at 23:05
  • I didn't. Someone else did. Still don't know why it happened. – Alex Zavatone Apr 24 '17 at 16:52
29

I have subsequently discovered that some web pages are correctly scaled, but some are not. For web pages which are not properly scaled, javascript can be used to control zooming as follows:

NSString *jsCommand = [NSString stringWithFormat:@"document.body.style.zoom = 1.5;"];
[webLookupView stringByEvaluatingJavaScriptFromString:jsCommand];
RunLoop
  • 20,288
  • 21
  • 96
  • 151
  • 1
    the problem with that method is that I can see it loads the page in the actual size, and a second later it updates itself with the right size... it looks not good. Do you have another solution? – Lior Frenkel Mar 29 '11 at 10:36
  • unfortunately I do not but I can suggest that you hide the webview until the zooming has been done. – RunLoop Apr 01 '11 at 04:23
  • CSS scaling are not suitable for many sites, so ```[scroll setZoomScale:animated:]``` is preferred, but you need to validate zoom to be in proper range! Seems like a bug in ```UIWebView``` class or strange behaviour. Please, check my comment above :) – rudyryk Oct 23 '13 at 18:30
23

You can use the below code:

self.webView.scalesPageToFit = YES;
self.webView.contentMode = UIViewContentModeScaleAspectFit;

in - (void)webViewDidFinishLoad:(UIWebView *)webView method or viewDidLoad

Homam
  • 5,018
  • 4
  • 36
  • 39
vualoaithu
  • 936
  • 10
  • 9
17

If you have access to the html you are loading you can chuck the following meta tag in the header :

<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
Mongus Pong
  • 11,337
  • 9
  • 44
  • 72
10

in Swift2

self.webView.scalesPageToFit = true
self.webView.contentMode = UIViewContentMode.ScaleAspectFit
Andrii Chernenko
  • 9,873
  • 7
  • 71
  • 89
idris yıldız
  • 2,097
  • 20
  • 22
2

My solution in swift:

"Scales pages to fit" on webView needs to be checked in interface builder.

Use UIWebViewDelegate.

func webViewDidFinishLoad(webView: UIWebView) {
    let zoom = webView.bounds.size.width / webView.scrollView.contentSize.width
    webView.scrollView.setZoomScale(zoom, animated: true)
}
Zoltan Vinkler
  • 1,207
  • 1
  • 15
  • 20
2

As mprivate mentions here you can update the zoom level of the UIWebView.

- (void)webViewDidFinishLoad:(UIWebView *)theWebView {
  CGSize contentSize = theWebView.scrollView.contentSize;
  CGSize viewSize = theWebView.bounds.size;

  float rw = viewSize.width / contentSize.width;

  theWebView.scrollView.minimumZoomScale = rw;
  theWebView.scrollView.maximumZoomScale = rw;
  theWebView.scrollView.zoomScale = rw;  
}

Another way of achieving this would be injecting js code on the webViewDidFinishLoad as RunLoop says.

- (void)webViewDidFinishLoad:(UIWebView *)webView {
  CGFloat scale = 0.8; // the scale factor that works for you 
  NSString *js = [NSString stringWithFormat:@"document.body.style.zoom = %f;",scale];
  [webView stringByEvaluatingJavaScriptFromString:js];
}
Community
  • 1
  • 1
Rodrigo Gonzalez
  • 723
  • 7
  • 15
2

Anybody looking for WKWebView answer, please try the below code:

extension YourViewController: WKNavigationDelegate {

    func webView(_ webView: WKWebView, didCommit 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);"
        webView.evaluateJavaScript(jscript)
    }
}

Remember to set the navigationDelegate of the Webview.

Mahendra Liya
  • 12,912
  • 14
  • 88
  • 114
1

For Swift 3, using RunLoop's effective answer:

self.webView.stringByEvaluatingJavaScript(from: "document.body.style.zoom = 1.5;")

Van
  • 73
  • 8
1

In xCode 8.3.3, go to the storyboard of the view/scene where the web view is located and check Scale Page to Fit in the attributes inspector section . Also select Scale to Fill as the content mode.

crissyg
  • 93
  • 3
-1

Try this in your ViewController's viewDidLoad

[self.myWebView setFrame:CGRectMake(self.view.frame.origin.x,
                                   self.view.frame.origin.y,
                                   self.view.frame.size.width,
                                   self.view.frame.size.height)];
  • I also have the webview set to "scalePageToFit" and viewmode set to "Aspect Fit" in my Storyboard.
Anthony De Souza
  • 544
  • 5
  • 10
  • 2
    This solution is wrong, and event then code could be simplified to ```self.myWebView.frame = self.view.bounds``` – aryaxt Jun 05 '15 at 22:44
-7

There is "Scale To Fit" option in interface builder, so it should be something programatic to do the same.

Kai
  • 27
  • 2
  • 1
    The OP knows this already, they are using the relevant property in the code in their question. –  Jun 26 '12 at 09:58