Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WKWebView+contentInset makes content size wrong

On iOS, when you set a contentInset on a WKWebView's scroll view, it seems to make the web view think the content of the page is bigger than it is. For example, if you give a mostly-empty page a top or bottom contentInset, you'll be able to scroll the page down even though there's nothing to scroll to.

Is this expected behavior? Is there a workaround that still allows me to use contentInset?

like image 444
phu Avatar asked Nov 25 '15 16:11

phu


3 Answers

The problem is that WKWebView always seems to use its frame as its viewport size, neglecting to subtract the scrollView's contentInset. I was able to find a workaround by stephan-leroux.

The idea is to set the WKWebView's frame to the desired viewport size, either manually or using autolayout constraints. To restore the "scroll-under" effect of contentInset, disable the scrollView's masksToBounds:

wkWebview.scrollView.layer.masksToBounds = NO;
like image 168
weiyin Avatar answered Oct 19 '22 13:10

weiyin


weiyin's suggestion (resizing the web view's frame) worked for me.

Just wanted to share a code example:

CGFloat topInset = ...;
web.scrollView.layer.masksToBounds = NO;
[web.scrollView setContentInset:UIEdgeInsetsMake(topInset, 0, 0, 0)];
[web setFrame:CGRectMake(0, 0, web.width, web.height-topInset)];
like image 2
bendytree Avatar answered Oct 19 '22 14:10

bendytree


Four years later and the problem still persists...

weiyin's answer works great, but if you're like me you might struggle a bit with figuring out what exactly to do (though it's really quite simple).

So here's a simple explanation for dummies (like me):

  1. Embed your Web View inside a Wrapper View.

  2. Size and position your Web View in a way that its frame is inset from the Wrapper View precisely by your desired content inset.

  3. Set clipsToBounds = false on the Web View's scroll view (and true on the Wrapper View).

  4. Make sure that there is no content inset set on the Web View (webview.contentInset = .zero).

    (This is the default and normally, you don't need to set it at all).

Done:

  • 100% content inset behavior on the Web View without using content insets.

Visual explanation of how to arrange the views

like image 1
Mischa Avatar answered Oct 19 '22 15:10

Mischa