Deciding height for UIScrollView with UIWebView in

2019-06-04 19:28发布

问题:

I have a detail view where I want to show a title, subtitle and content for articles. I want to be able to use HTML to format the text, so I've used a UIWebView for showing the article body. This works perfectly.

How ever, all of this, is inside a UIScrollView, so my issue is that I have to calculate the height of the UIScrollView?

This is how it works today:

And this is how it looks like in Storyboard:

So what I need to find out, is what is the correct code and syntax to calculate the correct height of the UIScrollView? Amongst several things, I tried [self.scrollView sizeToFit] without luck.

EDIT: Apparently it sets the correct heights with the code below, but seems like the view never updates.

-(void)webViewDidFinishLoad:(UIWebView *)webView
{
    // get height of content in webview
    CGFloat height = [[webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"] floatValue];

    // set new frame height
    CGRect frame = webView.frame;
    frame.size.height = height;
    webView.frame = frame; // webview is now correct height

    // set new frame height for scrollview (parent of webview)
    CGRect scrollFrame = self.scrollView.frame;
    scrollFrame.size.height = webView.frame.origin.y + height;
    self.scrollView.frame = scrollFrame;

    // log to console for cross checking
    NSLog(@"new frame: %f, scrollview frame: %f", scrollFrame.size.height, self.scrollView.frame.size.height);
}

The console reports the apparently correct height:

new frame: 582.000000, scrollview frame: 582.000000

And a quick check in Photoshop as well, this seems to be correct:

The summed value of green and blue area is 582 pixels, but the scrollview still just scrolls the 504 pixel area from below the navigation bar to the bottom of the screen (to the bottom of the tab bar).

回答1:

The webview has internally a scrollview. You can query its size by webview.scrollView.contentSize. You have to wait with this until the webview has finished rendering.

So, in the -webViewDidFinishLoad: delegate method you can get the optimal height of the webView through webView.scrollView.contentSize.height. You can then resize the webView to this height and layout the other views appropriately. If all of this is done in a custom view, the proper way of doing this would probably be to just call [theView setNeedsLayout] and override -layoutSubviews in theView.

You also should set webView.scrollView.alwaysBounceVertically to NO.



回答2:

I solved the problem.

First of all, just expand the UIWebView to a height higher than the content ever will be (e.g. 2000 pixels).

The delegate method code that makes the magic happen

-(void)webViewDidFinishLoad:(UIWebView *)webView
{
    // set height for webiew
    webView.autoresizesSubviews = NO;
    webView.translatesAutoresizingMaskIntoConstraints = YES;
    webView.scrollView.autoresizesSubviews = NO;
    webView.scrollView.translatesAutoresizingMaskIntoConstraints = YES;

    CGFloat height = [[webView stringByEvaluatingJavaScriptFromString:@"document.getElementById('content').clientHeight;"] floatValue] + 80; // +80 for tabbar and spacing
    CGRect frame = webView.frame;
    frame.size.height = height;
    webView.frame = frame;

    // fix height of scroll view as well
    self.scrollView.translatesAutoresizingMaskIntoConstraints = YES;
    self.scrollView.contentSize = CGSizeMake(320, (self.webView.frame.origin.y + self.webView.frame.size.height));
}