Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zooming on UIWebView

I have a UIWebView which I'm using to display a variety of content, sometimes HTML and sometimes PDF/Powerpoint/etc (which is all seemingly handled by the same underlying control).

What I want to do is harness the underlying UIScrollView (a subview of the UIWebView) to capture the exact perspective of the scroll view and recreate the scroll position in another UIWebView, thus keeping them both in sync.

The problem that I'm having is that the zoomScale property of the UIScrollView is always 1.0 while displaying HTML content (though when displaying PDF content, zoomScale is correct).

I managed to find that the only place where I can get any inkling of the zoom scale of an HTML page is in the scrollViewDidEndZooming:withView:atScale: delegate method. I've found that the atScale: argument seems to provide a relative zoom scale, to what the zoom scale was before the zooming operation began. So for example when zooming in, that argument is >1, and when zooming out it is <1, and it seems to be a relative value between the two zoom scales rather than an absolute zoom scale).

What I've further found is that fundamentally, HTML and PDF content is handled by two different underlying views: there's UIWebBrowserView which handles HTML content, and UIWebPDFView to handle displaying of PDFs.

So in other words, when using a UIWebPDFView, the zoomScale property of the UIScrollView is completely reliable (e.g. 1.0 for zoomed-out, 2.4 for zoomed-in, for example). On the other hand, UIWebBrowserView is much more fiddly, and when asking the UIScrollView for its zoomScale, always returns 1.0, but when receiving the delegate callback, receives a scale value that is a relative value.

So my questions are:-

  1. Is this a bug? (This behaviour is seen on both iOS 4 and 5 from what I've seen).

  2. How can I get both the zoomScale (or some other property/properties) for both HTML and PDF content, and get it in such a way that the state can be duplicated and kept in sync with another UIWebView.

I'm not beholden to using zoomScale, so I'm open to other suggestions for how the scroll state of a UIWebView can be captured and reproduced on another UIWebView.

like image 922
Jonathan Ellis Avatar asked Nov 21 '11 15:11

Jonathan Ellis


4 Answers

When loading HTML, and UIWebBrowserView is being used, you can use

zoomScale = 1.0 / webView.scrollView.minimumZoomScale

Of course this is assuming that you can reliably ensure that the minimum zoom of your HTML page is 1.0, since some pages can alter the minimum zoom using the "viewport" meta tag.

like image 189
James Hu Avatar answered Sep 27 '22 22:09

James Hu


Have you tried this?

set scalesPageToFit=YES;

That's the most common way to deal with the problem i think. Setting that enables you to pinch and zoom UIWebView.I don't think you can actually zoom in/out UIWebView without that.

Now the zoom is going to be relative to whatever you're showing on your UIWebView. If it is a big table, it's not so close but it's a good start point if you're going to pinch for zoom in.

like image 26
Farini Avatar answered Sep 27 '22 22:09

Farini


This Logic for zooming of UIWebView, no need to add UIWebView on UIScrollView

Well only problem with webView.scalesPageToFit=YES; is, it change initial content font size but I have got other option by my self, Its working very well for me.

Add <UIWebViewDelegate, UIScrollViewDelegate> to your .h file

Creation of your UIWebView.

self.mWebview = [[UIWebView alloc] init];
self.mWebview.delegate = self; /// set delegate method of UIWebView
self.mWebview.frame = CGRectMake(0, 35, self.view.bounds.size.width, self.view.bounds.size.height - 80); // set frame whatever you want..
[self.mWebview setOpaque:NO];
self.mWebview.backgroundColor = [UIColor clearColor];
[self.view addSubview:self.mWebview];

With load HTML file/content.

NSString* htmlString = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"File Name"ofType:@"html"] encoding:NSUTF8StringEncoding error:nil];
[self.mWebview loadHTMLString:htmlString baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];


#pragma mark -
#pragma mark - Webview Delegate Methods

- (void) webViewDidFinishLoad:(UIWebView *)webView
{
    webView.scrollView.delegate = self; // set delegate method of UISrollView
    webView.scrollView.maximumZoomScale = 20; // set as you want.
    webView.scrollView.minimumZoomScale = 1; // set as you want.

    //// Below two line is for iOS 6, If your app only supported iOS 7 then no need to write this.
    webView.scrollView.zoomScale = 2;
    webView.scrollView.zoomScale = 1;
}

#pragma mark -
#pragma mark - UIScrollView Delegate Methods

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{
    self.mWebview.scrollView.maximumZoomScale = 20; // set similar to previous.
}

NOTE: I had to tested on Mac OS X - 10.9.3 with Xcode 5.1.1 and iOS version 6.1 and latter.

I hope this will helpful for you. :)

like image 43
iPatel Avatar answered Sep 27 '22 23:09

iPatel


Unfortunately the only way I found to get the actual scale of the web content in a UIWebView is by accessing to a private member of the UIWebBrowserView : initialScale.

float initialScale = (access to [UIWebBrowserView initialScale])
float zoomScale = 1.0 / webView.scrollView.minimumZoomScale;
float actualScale = zoomScale * initialScale;

I am wondering if this can be done without accessing to private member.

like image 40
ebtokyo Avatar answered Sep 27 '22 22:09

ebtokyo