ioscordovaphonegapiphone-x

Cordova app not displaying correctly on iPhone X (Simulator)


I tested my Cordova-based app yesterday on the iPhone X Simulator in Xcode 9.0 (9A235) and it didn't look good. Firstly, instead of filling the full screen area, there was a black area above and below the app content. And worse, between the app content and the black was two white bars.

Adding cordova-plugin-wkwebview-engine so Cordova renders using WKWebView (not UIWebView) fixes the white bars. By my app is not migrated from UIWebView to WKWebView due to performance and memory leak issues when using cordova-plugin-wkwebview-engine which occur when loading images downloaded from Inapp Purchase hosted content into an HTML5 canvas (direct file:// access by the Webview is not possible due to security restrictions in WKWebView so the image data must be loaded via cordova-plugin-file).

These screenshots show a test app with a blue background set on the <body>. Above and below UIWebView, you can see the white bars, but not with WKWebView:


(source: pbrd.co)


(source: pbrd.co)

Both Cordova Webviews exhibit the black areas when compared to a native app which fills the full screen area:


Solution

  • I found the solution to the white bars here:

    Set viewport-fit=cover on the viewport <meta> tag, i.e.:

    <meta name="viewport" content="initial-scale=1, width=device-width, height=device-height, viewport-fit=cover">
    

    The white bars in UIWebView then disappear:

    The solution to remove the black areas (provided by @dpogue in a comment below) is to use LaunchStoryboard images with cordova-plugin-splashscreen to replace the legacy launch images, used by Cordova by default. To do so, add the following to the iOS platform in config.xml:

    <platform name="ios">    
        <splash src="res/screen/ios/Default@2x~iphone~anyany.png" />
        <splash src="res/screen/ios/Default@2x~iphone~comany.png" />
        <splash src="res/screen/ios/Default@2x~iphone~comcom.png" />
        <splash src="res/screen/ios/Default@3x~iphone~anyany.png" />
        <splash src="res/screen/ios/Default@3x~iphone~anycom.png" />
        <splash src="res/screen/ios/Default@3x~iphone~comany.png" />
        <splash src="res/screen/ios/Default@2x~ipad~anyany.png" />
        <splash src="res/screen/ios/Default@2x~ipad~comany.png" />   
    
        <!-- more iOS config... -->
    </platform>
    

    Then create the images with the following dimensions in res/screen/ios (remove any existing ones):

    Default@2x~iphone~anyany.png - 1334x1334
    Default@2x~iphone~comany.png - 750x1334
    Default@2x~iphone~comcom.png - 1334x750
    Default@3x~iphone~anyany.png - 2208x2208
    Default@3x~iphone~anycom.png - 2208x1242
    Default@3x~iphone~comany.png - 1242x2208
    Default@2x~ipad~anyany.png - 2732x2732
    Default@2x~ipad~comany.png - 1278x2732
    

    Once the black bars are removed, there's another thing that's different about the iPhone X to address: The status bar is larger than 20px due to the "notch", which means any content at the far top of your Cordova app will be obscured by it:

    Rather than hard-coding a padding in pixels, you can handle this automatically in CSS using the new safe-area-inset-* constants in iOS 11.

    Note: in iOS 11.0 the function to handle these constants was called constant() but in iOS 11.2 Apple renamed it to env() (see here), therefore to cover both cases you need to overload the CSS rule with both and rely on the CSS fallback mechanism to apply the appropriate one:

    body{
        padding-top: constant(safe-area-inset-top);
        padding-top: env(safe-area-inset-top);
    }
    

    The result is then as desired: the app content covers the full screen, but is not obscured by the "notch":

    I've created a Cordova test project which illustrates the above steps: webview-test.zip

    Notes:

    Footer buttons

    .toolbar-footer{
        margin-bottom: constant(safe-area-inset-bottom);
        margin-bottom: env(safe-area-inset-bottom);
    }
    

    cordova-plugin-statusbar

    splashscreen

    device orientation

    For reference, this is the original Cordova issue I opened which captures this: https://issues.apache.org/jira/browse/CB-13273