3

I added a WKWebView subview into a PhoneGap / Cordova 4.0+ app (via cordova-plugin-wkwebview-engine) and used programmatic AutoLayout constraints to get the WKWebView to size the same as the MainViewController's view.

When I view the bounds of the WKWebView, it matches the MainViewController view's bounds.

But using Javascript to inspect the content size, specifically script that looks like:

var body = document.body; 
var html = document.documentElement;
Math.max(body.scrollHeight,body.offsetHeight,html.clientHeight,html.offsetHeight);

This returns a height that's actually about 1/2 to 2/3rds of the WKWebView bounds height (on an iPad Pro simulator I'm setting bounds height to 1024.0 but the Javascript reports a content height of only 735.0). And I'm only displaying half of the non-resizing Vue.js content I'd love to display.

Since I can't show the actual content I'm working with (NDA fun!), I actually noticed the problem happens with any URL I pass into WKWebView within PhoneGap/Cordova. Here is what apple.com looks like in my app: Bottom Edge is Cut Off

And here is what it should look like, the correctly sized version, in Mobile Safari (running in the simulator):

More Being Displayed

You can see the top bar items are differently spaced (on the desktop they're supposed to be indented from either side of the window somewhat) and there's more revealed in the bottom edge, because the web view's internal height is taller.

To fix my problem, I've done everything from move the WKWebView instantiation from viewDidLoad out to viewDidAppear, and also tried "hard coding" a static iPad Pro-sized framesize being passed into [WKWebView initWithFrame:], but content size remains at 735.0. This same content renders beautifully (and correctly) both in the Simulator's Mobile Safari and in Desktop Safari.

How can I force WKWebView's content size to match the bounds of the parent view?

If you'd like to see this bug in action on the iPad Pro simulator, I have a public github repo at https://github.com/dautermann/phonegap-air. Be sure to fetch the "demonstrate-issue" branch.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
  • when i try, i can see apple.com with 4 columns in my `WKWebView`. where/in which method do you inspect `contentSize`? – Mert Buran Mar 03 '17 at 15:04
  • are you doing this in a Cordova app? As for where I am running that javascript, it's currently living in MainViewController's `viewDidAppear:` method. I got the same result in `viewWillAppear` and `viewDidLoad`. – Michael Dautermann Mar 03 '17 at 15:19
  • @MichaelDautermann By any chance are you using statusbar plugin? – Gandhi Mar 08 '17 at 15:28
  • Not that I know of. I didn't install one explicitly. How can I determine if one is installed by accident or as part of something else? – Michael Dautermann Mar 08 '17 at 15:29
  • @MichaelDautermann If its installed you will find it in your project's plugin folder. – Gandhi Mar 09 '17 at 06:23

2 Answers2

1

Short answer:

You need to inspect contentSize in your WKNavigationDelegate's webView:didFinishNavigation: method, until here you only get 735.0 as contentSize with your JavaScript code.

A little longer answer

When you create your WKWebView, its frame has the same size in initwithFrame's frame. It doesn't change until autolayout works its magic, namely until viewDidLayoutSubviews method in your UIViewController.

At this point, you have a WKWebView which covers the main view but your website's contentSize is not what you expected. Because your website is not there yet.

You need to set webView.navigationDelegate = {delegate} to listen to navigation events. Your website isn't %100 there until delegate is called via webView:didFinishNavigation: method. From now on, you can measure the expected contentSize value.

Hope that helps.

Mert Buran
  • 2,989
  • 2
  • 22
  • 34
  • I'll give this a try in a just a few. What I can tell you is that the frame I send in via `WKWebView initWithFrame:` has a `size.height` of 1024.0, but what's coming out even after multiple `loadRequest:` is a height of 735.0. That's from the Javascript query I pass into the WKWebView. The bounds and frame CGRect properties of the WKWebView are actually correctly sized (i.e. much taller than 735.0). – Michael Dautermann Mar 03 '17 at 15:22
  • https://gist.github.com/buranmert/204decdb5c5f0f06a77129de9d45936e here is the code that i tried (with the values i get). the weird thing is i can't reproduce 2-column-apple.com in my sample project which is just a simple WKWebView – Mert Buran Mar 03 '17 at 15:29
  • I *think* the reason you're not reproducing this is because you appear to be using a WKWebView simply dropped into a non-Cordova / non-Phonegap app. My WKWebview instantiation is happening in a file named `CDVWKWebViewEngine.m`, which is part of the `cordova-plugin-wkwebview-engine`. – Michael Dautermann Mar 03 '17 at 18:50
  • can you try to add observer to `CDVPageDidLoadNotification` notification and measure `contentSize` after it is fired? https://github.com/apache/cordova-plugin-wkwebview-engine/blob/master/src/ios/CDVWKWebViewEngine.m#L376 – Mert Buran Mar 04 '17 at 14:08
  • Thanks for sticking with me on this. When `CDVPageDidLoadNotification` fires, I'm now getting a contentSize of 1453 (!). Much better than 735.0. Unfortunately, I'm still only seeing two columns in my apple.com WKWebView. I've now pushed a [demonstration github repo](https://github.com/dautermann/phonegap-air/tree/demonstrate-issue) if you want to see exactly what I'm seeing. – Michael Dautermann Mar 05 '17 at 12:47
  • +1 to you because I didn't implement the CDVPageDidLoadNotification bit correctly (I was handling my own navigation delegate methods and wasn't sure how to call `super` on that) – Michael Dautermann Mar 10 '17 at 14:08
1

I think the issue you have is not directly related to the WebView. It is related to the fact that for the backward compatibility reasons "old" applications run on iPad Pro do not get "native resolution" and use iPad 1024x768 instead.

The way to persuade Apple that you are aware of the iPad Pro and its native resolution is to specify some LaunchScreen storyboard. Yes, this is a bit surprising way but this is what it is (see for example https://forums.developer.apple.com/thread/17193). If I modify the OTAApplication target in your test project on GitHub and specify standard CDVLaunchScreen as Launch Screen File everything works fine for me.

Update

According to Force iPad Pro to full resolution without Launch Screen if you use XCode 8, it might be enough to just specify Launch Image of proper resolution for iPad Pro. Haven't tried it though.

Community
  • 1
  • 1
SergGr
  • 23,570
  • 2
  • 30
  • 51