HTML Content fit in UIWebview without zooming out

IphoneObjective CUiwebview

Iphone Problem Overview


I am making use of the UIWebView to render some HTML. However, although the width of my webview is 320 my HTML is still shown full width and can be scrolled horizontally.

I want to achieve the same thing the native mail application achieves which is it fits all content within that width without zooming out - how does the native mail application render HTML like this?

Update

I thought making use of the viewport meta tag will help, but I couldn't get this to work.

This is what is happening:

enter image description here

As you can see the content does not fit the device width. I've tried so many combinations of viewport meta tag. The below is an example of what happens when I try Martins suggestion.

Original HTML is can be found here.

The way this HTML is rendered by the native mail application is like so.

Iphone Solutions


Solution 1 - Iphone

Here's what you do:

In your UI controller that owns the web view, make it a UIWebViewDelegate. Then where you set the URL to load, set the delegate as the controller:

NSString *urlAddress = @"http://dl.dropbox.com/u/50941418/2-build.html";
NSURL *url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObj];  
webView.delegate = self;

And finally implement the webViewDidFinishLoad: to correctly set the zoom level:

This option will applicable from iOS 5.0 and >

- (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;  
}

I hope this helps...

Option B, you can try to alter the HTML (this example does the job but is less than perfect from an HTML parsing standpoint. I just wanted to illustrate my point. It does work for your example, and probably most cases. The inset of 40 can probably be detected programmatically, I didn't try to research that.

NSString *urlAddress = @"http://dl.dropbox.com/u/50941418/2-build.html";
NSURL *url = [NSURL URLWithString:urlAddress];

NSString *html = [NSString stringWithContentsOfURL:url encoding:[NSString defaultCStringEncoding] error:nil];
NSRange range = [html rangeOfString:@"<body"];

if(range.location != NSNotFound) {
  // Adjust style for mobile
  float inset = 40;
  NSString *style = [NSString stringWithFormat:@"<style>div {max-width: %fpx;}</style>", self.view.bounds.size.width - inset];
  html = [NSString stringWithFormat:@"%@%@%@", [html substringToIndex:range.location], style, [html substringFromIndex:range.location]];
}

[webView loadHTMLString:html baseURL:url];

Solution 2 - Iphone

Just add this:

webView.scalesPageToFit = YES;

Solution 3 - Iphone

Typically, you should use the viewport meta tag. But its use is very erratic, mostly if you want a cross platform web page.

It also depends of what content and css you have.

For my iPhone homepage, which must auto-resize from portrait to lanscape, I use this :

<meta name="viewport" content="width=device-width; minimum-scale=1.0; maximum-scale=1.0; user-scalable=no">

If you need special resize, you can also use the event :

<body onorientationchange="updateOrientation();">

with the corresponding funciton in your javascript :

function updateOrientation() {
  if(Math.abs(window.orientation)==90)
	  // landscape
  else
      // portrait	
}

EDIT :

Seeing you page source, it seems you made it with a web editor, don't you ?

Ok, I understand. Your main div has a width of 600px. The iphone screen resolution is 320x480. 600 > 320 so it exceeds the screen bounds.

Now, let's make some simple operations:

320 / 600 = 0.53
480 / 600 = 0.8

So you want to zoom out 0.5 times minimum and 0.8 times maximum. Lets change the viewport :

<meta name="viewport" content="width=device-width; minimum-scale=0.5; maximum-scale=0.8; user-scalable=no"> 

Solution 4 - Iphone

What worked for me was to select the UIWebView in Interface Builder and check the box that says "Scales Page To Fit":

enter image description here

Solution 5 - Iphone

@implementation UIWebView (Resize)

- (void)sizeViewPortToFitWidth {
    [self stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.querySelector('meta[name=\"viewport\"]').setAttribute('content', 'width=%d;', false); ", (int)self.frame.size.width]];
}

@end

Solution 6 - Iphone

Swift 3:

>Use this extension to resize contents of webview according to size of a webview.

extension UIWebView {
    ///Method to fit content of webview inside webview according to different screen size
    func resizeWebContent() {
        let contentSize = self.scrollView.contentSize
        let viewSize = self.bounds.size
        let zoomScale = viewSize.width/contentSize.width
        self.scrollView.minimumZoomScale = zoomScale
        self.scrollView.maximumZoomScale = zoomScale
        self.scrollView.zoomScale = zoomScale
    }
}

How to invoke?

webViewOutlet.resizeWebContent()

Solution 7 - Iphone

You may generate an NSAttributedString from HTML (do it on background):

@implementation NSAttributedString (Utils)

+ (void)parseHTML:(NSString *)html withCompletion:(void (^)(NSAttributedString *completion, NSError *error))completion
{
	dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
		NSError * __autoreleasing *error = nil;
		NSAttributedString *result = [[NSAttributedString alloc] initWithData:[html dataUsingEncoding:NSUTF8StringEncoding]
																	  options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
																				NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)}
														   documentAttributes:nil error:error];
		NSError *safeError = (error != nil) ? *error : nil;
		dispatch_sync(dispatch_get_main_queue(), ^(void){
			completion(result, safeError);
		});
	});
}
      
@end

And show it through UITextView instance:

[NSAttributedString parseHTML:htmlString withCompletion:^(NSAttributedString *parseResult, NSError *error) {
		bodyTextView.attributedText = parseResult;
}];

Some layout features, though, may corrupt with this approach.

Solution 8 - Iphone

i solved the issue by unticking "scales page to fit" enter image description here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAbsView Question on Stackoverflow
Solution 1 - IphonemprivatView Answer on Stackoverflow
Solution 2 - IphoneDenisView Answer on Stackoverflow
Solution 3 - IphoneMartinView Answer on Stackoverflow
Solution 4 - IphoneChris LivdahlView Answer on Stackoverflow
Solution 5 - IphoneWerner AltewischerView Answer on Stackoverflow
Solution 6 - Iphoneaashish tamsyaView Answer on Stackoverflow
Solution 7 - IphonenrxView Answer on Stackoverflow
Solution 8 - IphoneOmar N ShamaliView Answer on Stackoverflow