L'application Cordova ne s'affiche pas correctement sur l'iPhone X (Simulateur)

121

J'ai testé mon application basée sur Cordova hier sur le simulateur iPhone X dans Xcode 9.0 (9A235) et cela n'avait pas l'air bien. Tout d'abord, au lieu de remplir la zone plein écran, il y avait une zone noire au-dessus et en dessous du contenu de l'application. Et pire, entre le contenu de l'application et le noir, il y avait deux barres blanches.

L'ajout de cordova-plugin-wkwebview-enginesorte que Cordova rende à l'aide de WKWebView (et non de UIWebView) corrige les barres blanches. Par mon application n'est pas migré d'UIWebView vers WKWebView en raison de problèmes de performances et de fuites de mémoire lors de l'utilisation cordova-plugin-wkwebview-enginequi se produisent lors du chargement d'images téléchargées à partir d'Inapp Achetez du contenu hébergé dans un canevas HTML5 (l' file://accès direct par Webview n'est pas possible en raison des restrictions de sécurité dans WKWebView donc les données d'image doivent être chargées via cordova-plugin-file).

Ces captures d'écran montrent une application de test avec un arrière-plan bleu défini sur le <body>. Au-dessus et en dessous de UIWebView, vous pouvez voir les barres blanches, mais pas avec WKWebView:


(source: pbrd.co )


(source: pbrd.co )

Les deux Webviews Cordova présentent les zones noires par rapport à une application native qui remplit la zone plein écran:

DaveAlden
la source
Intéressant avec wkwebview. Dans mon jeu, je n'avais pas la pleine largeur, mais aussi un décalage par rapport au centre. Dans uiwebview, il a gardé la même taille, mais se centre au moins.
agmcleod
J'ai eu ce problème aussi, alors j'ai fait une solution de contournement avec juste css voir pt.stackoverflow.com/a/263460/55076
Igor Trindade
J'ai aussi ce problème. Le <meta>simple fait d' ajouter la balise à mon fichier cordova index.hml comme d'autres énumérés ci-dessous ne fonctionne pas. J'utilise Cordova 7x avec cordova-ios 4.5.4 - y a-t-il autre chose que je dois faire?
rolinger

Réponses:

246

J'ai trouvé la solution aux barres blanches ici :

Défini viewport-fit=coversur la <meta>balise de la fenêtre , c'est-à-dire:

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

Les barres blanches dans UIWebView disparaissent alors:

La solution pour supprimer les zones noires (fournies par @dpogue dans un commentaire ci-dessous) consiste à utiliser les images LaunchStoryboard avec cordova-plugin-splashscreenpour remplacer les anciennes images de lancement, utilisées par défaut par Cordova. Pour ce faire, ajoutez ce qui suit à la plate-forme iOS dans 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>

Créez ensuite les images avec les dimensions suivantes dans res/screen/ios(supprimez toutes les images existantes):

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

Une fois les barres noires supprimées, il y a une autre chose différente à propos de l'iPhone X: la barre d'état est plus grande que 20 pixels en raison de l '«encoche», ce qui signifie que tout contenu tout en haut de votre application Cordova sera masqué par elle. :

Plutôt que de coder en dur un remplissage en pixels, vous pouvez gérer cela automatiquement dans CSS en utilisant les nouvelles safe-area-inset-*constantes d'iOS 11.

Remarque: dans iOS 11.0, la fonction permettant de gérer ces constantes a été appelée, constant()mais dans iOS 11.2, Apple l'a renommée env()( voir ici ), par conséquent, pour couvrir les deux cas, vous devez surcharger la règle CSS avec les deux et compter sur le mécanisme de secours CSS pour appliquer le approprié:

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

Le résultat est alors celui souhaité: le contenu de l'application couvre le plein écran, mais n'est pas masqué par le "cran":

J'ai créé un projet de test Cordova qui illustre les étapes ci-dessus: webview-test.zip

Remarques:

Boutons de pied de page

  • Si votre application possède des boutons de pied de page (comme le mien), vous devrez également postuler safe-area-inset-bottompour éviter qu'ils ne soient superposés par le bouton d'accueil virtuel de l'iPhone X.
  • Dans mon cas, je ne pouvais pas appliquer cela à <body>car le pied de page est absolument positionné, je devais donc l'appliquer directement au pied de page:

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

cordova-plugin-statusbar

  • La taille de la barre d'état a changé sur l'iPhone X, les anciennes versions de l' cordova-plugin-statusbaraffichage ne s'affichent donc pas correctement sur l'iPhone X
  • Mike Hartington a créé cette pull request qui applique les modifications nécessaires.
  • Cela a été fusionné dans la [email protected]version, alors assurez-vous que vous utilisez au moins cette version pour appliquer aux insertions de zone de sécurité

écran de démarrage

  • Les contraintes du storyboard LaunchScreen ont changé sur iOS 11 / iPhone X, ce qui signifie que l'écran de démarrage a semblé "sauter" au lancement lors de l'utilisation des versions existantes du plugin ( voir ici ).
  • Cela a été capturé dans le rapport de bogue CB-13505 , corrigé PR cordova-ios # 354 et publié dans [email protected], alors assurez-vous d'utiliser une version récente de la cordova-iosplate - forme.

orientation de l'appareil

  • Lorsque vous utilisez UIWebView sur iOS 11.0, la rotation de portrait> paysage> portrait empêche la safe-area-insetréapplication du contenu, ce qui rend le contenu à nouveau masqué par l'encoche (comme souligné par jms dans un commentaire ci-dessous).
  • Se produit également si l'application est lancée en mode paysage puis tournée en portrait
  • Cela ne se produit pas lors de l'utilisation de WKWebView via cordova-plugin-wkwebview-engine.
  • Rapport radar: http://www.openradar.me/radar?id=5035192880201728
  • Mise à jour : cela semble avoir été corrigé dans iOS 11.1

Pour référence, il s'agit du numéro original de Cordova que j'ai ouvert et qui capture ceci: https://issues.apache.org/jira/browse/CB-13273

DaveAlden
la source
3
Avez-vous des problèmes lorsque vous faites pivoter l'écran? J'ai essayé, mais après la rotation de l'écran, tout est cassé (safe-area-inset- * ne met pas à jour leurs valeurs en fonction de l'orientation de l'appareil; et après la rotation du portrait -> paysage -> portrait à nouveau, les valeurs initiales sont également cassées ). Cela pourrait-il être un problème avec le navigateur Apple / Safari?
Juan Miguel S.
1
Dans mon cas, lorsque j'ai ajouté viewport-fit=covertoute mon application n'affiche qu'un écran blanc vide et rien d'autre. J'utilise iOS11, Xcode9 sur iPhone 7 Plus. Quelqu'un a-t-il un comportement similaire?
Dimitri
1
@DaveAlden - il semble que 11.2 bêta + ils ont chuté constantpour envmot - clé - voir aussi: webkit.org/blog/7929/designing-websites-for-iphone-x
Brent
1
où mettez-vous le code css du corps dans votre application? Comme dans quel fichier? Rien ne fonctionne pour moi, j'utilise Ionic 3.
Dimitri
2
Y a-t-il une mise à jour concernant le problème de rotation? Je suis sous iOS 12 et rencontre le même problème. Cela me semble étrange que ce problème persiste. / cc @jms
a - m
36

Pour une correction manuelle à un projet cordova existant

Les barres noires

Ajoutez ceci à votre fichier info.plist . La correction de l'image de lancement est un problème distinct, c'est- à- dire comment ajouter une image de lancement iPhoneX

<key>UILaunchStoryboardName</key>
<string>CDVLaunchScreen</string>

Les barres blanches

Définissez viewport-fit = cover dans la balise Meta

<meta name="viewport" content="initial-scale=1, width=device-width, height=device-height, viewport-fit=cover">
codeur
la source
Merci! Le changement de .plist a le même effet que les changements de la réponse sélectionnée, mais beaucoup plus rapide.
2Fwebd
Que fait chacune de ces tâches sur la hauteur et la largeur des pixels CSS? Mon application a une série de divs étroits en haut (menus, etc.) ... puis je calcule la hauteur de pixel restante pour que le dernier DIV remplisse le reste de l'écran. À l'heure actuelle, je peux voir la barre blanche inférieure couvrir une partie de ce DIV, mais je peux aussi ne pas tout dire - ce qui implique que le DIV ne va toujours pas au bas de l'écran. Et à son tour, mon application commence sous la barre blanche supérieure, donc elle n'essaye même pas d'utiliser l'espace supérieur.
rolinger
Je l'ai utilisé UILaunchStoryboardNameet il a réussi à supprimer les barres noires. Mais mon écran de démarrage s'agrandit. Une raison pourquoi? La réponse acceptée ne fonctionne pas pour moi
Huiting
@coder Merci - mais l'ajout de UILaunchStoryboardName au plist m'empêche de pouvoir soumettre à l'App Store: ERREUR ITMS-90705: "Lancer le storyboard introuvable. Assurez-vous de spécifier le nom de fichier du storyboard de lancement sans extension de nom de fichier pour la clé UILaunchStoryboardName dans Info.plist. "
Matt Roberts
@Huiting avez-vous trouvé une solution à votre cas?
LMaker
16

Il y a 3 étapes à suivre

pour les problèmes de barre d'état iOs 11 et d'en-tête iPhone X


1. Couvercle d'ajustement de la fenêtre

Ajouter viewport-fit=coverà la méta de votre fenêtre d'affichage<header>

<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0,viewport-fit=cover">

Démo: https://jsfiddle.net/gq5pt509 (index.html)


  1. Ajoutez plus d'images de démarrage à votre config.xmlintérieur<platform name="ios">

Ne sautez pas cette étape , cela est nécessaire pour que l' écran s'adapte au travail sur iPhone X

<splash src="your_path/Default@2x~ipad~anyany.png" />   <!-- 2732x2732 -->
<splash src="your_path/Default@2x~ipad~comany.png" />   <!-- 1278x2732 -->
<splash src="your_path/Default@2x~iphone~anyany.png" /> <!-- 1334x1334 -->
<splash src="your_path/Default@2x~iphone~comany.png" /> <!-- 750x1334  -->
<splash src="your_path/Default@2x~iphone~comcom.png" /> <!-- 1334x750  -->
<splash src="your_path/Default@3x~iphone~anyany.png" /> <!-- 2208x2208 -->
<splash src="your_path/Default@3x~iphone~anycom.png" /> <!-- 2208x1242 -->
<splash src="your_path/Default@3x~iphone~comany.png" /> <!-- 1242x2208 -->

Démo: https://jsfiddle.net/mmy885q4 (config.xml)


  1. Corrigez votre style sur CSS

Utilisez safe-area-inset-left, safe-area-inset-right, safe-area-inset-topousafe-area-inset-bottom

Exemple: (à utiliser dans votre cas!)

#header {
   position: fixed;
   top: 1.25rem; // iOs 10 or lower
   top: constant(safe-area-inset-top); // iOs 11
   top: env(safe-area-inset-top); // iOs 11+ (feature)

   // or use calc()
   top: calc(constant(safe-area-inset-top) + 1rem);
   top: env(constant(safe-area-inset-top) + 1rem);
  
   // or SCSS calc()
   $nav-height: 1.25rem;
   top: calc(constant(safe-area-inset-top) + #{$nav-height});
   top: calc(env(safe-area-inset-top) + #{$nav-height});
}

Bonus: vous pouvez ajouter une classe de corps comme is-androidou is-iossur deviceready

var platformId = window.cordova.platformId;
if (platformId) {
   document.body.classList.add('is-' + platformId);
}

Vous pouvez donc faire quelque chose comme ça sur CSS

.is-ios #header {
 // Properties
}
l2aelba
la source
5

Dans mon cas où chaque écran de démarrage a été conçu individuellement au lieu d'être généré automatiquement ou disposé dans un format de storyboard, j'ai dû m'en tenir à ma configuration d'écran de lancement hérité et ajouter des images portrait et paysage pour cibler les orientations iPhoneX 1125 × 2436 au config.xml ainsi:

<splash height="2436" src="resources/ios/splash/Default-2436h.png" width="1125" />
<splash height="1125" src="resources/ios/splash/Default-Landscape-2436h.png" width="2436" />

Après avoir ajouté ceux-ci à config.xml ("viewport-fit = cover" était déjà défini dans index.hml), mon application créée avec Ionic Pro remplit tout l'écran sur les appareils iPhoneX.

TaeKwonJoe
la source
monsieur mais dans mon config.xml j'ai déjà ajouté au-dessus de cette ligne et viewport-fit = cover
Kapil soni
@Kapilsoni alors cela pourrait être un problème avec le plugin Cordova UIWebView, WKWebView, SplashScreen, ou une combinaison de ces configurations. En outre, ciblez-vous XCode 10 ou 11 dans vos versions?
TaeKwonJoe
monsieur je cible XCode 10?
Kapil soni
2

Correction du problème de rotation de l'écran de l'iPhone X / XS

Sur l'iPhone X / XS, une rotation de l'écran entraînera l'utilisation d'une valeur incorrecte par la hauteur de la barre d'en-tête, car le calcul de safe-area-inset- * ne reflétait pas les nouvelles valeurs à temps pour l'actualisation de l'interface utilisateur. Ce bogue existe dans UIWebView même dans le dernier iOS 12. Une solution de contournement consiste à insérer une marge supérieure de 1px puis à l'inverser rapidement, ce qui déclenchera le recalcul immédiat de safe-area-inset- *. Une solution quelque peu moche mais qui fonctionne si vous devez rester avec UIWebView pour une raison ou une autre.

window.addEventListener("orientationchange", function() {
    var originalMarginTop = document.body.style.marginTop;
    document.body.style.marginTop = "1px";
    setTimeout(function () {
        document.body.style.marginTop = originalMarginTop;
    }, 100);
}, false);

Le but du code est de modifier légèrement le document.body.style.marginTop, puis de l'inverser. Il ne doit pas nécessairement être "1px". Vous pouvez choisir une valeur qui ne fait pas clignoter votre interface utilisateur, mais qui atteint son objectif.

YYL
la source
UIWebView a été déprécié dans iOS8 ... Je doute que l'un des bogues existants soit corrigé. Apple avertit lors du téléchargement d'applications que cela sera bientôt interrompu ... il est donc temps de prendre la peine et de migrer vers WKWebView ...
Mozfet
2

Je développe des applications cordova depuis 2 ans et j'ai passé des semaines à résoudre des problèmes connexes (par exemple: la vue Web défile lorsque le clavier est ouvert). Voici une solution testée et éprouvée pour iOS et Android

PS: j'utilise iScroll pour faire défiler le contenu

  1. N'utilisez jamais viewport-fit = cover dans la balise meta de index.html, laissez l'application en dehors de la barre d'état. iOS gérera la zone appropriée pour toutes les variantes d'iPhone.
  2. Dans XCode, décochez Masquer la barre d'état et nécessite un plein écran et n'oubliez pas de sélectionner Lancer le fichier d'écran comme CDVLaunchScreen
  3. Dans config.xml, définissez le plein écran sur false
  4. Enfin, (merci à Eddy Verbruggen pour ses excellents plugins) ajoutez son plugin cordova-plugin-webviewcolor pour définir la barre d'état et la couleur d'arrière-plan de la zone inférieure. Ce plugin vous permettra de définir la couleur de votre choix.
  5. Ajoutez ci-dessous à config.xml (le premier ff après x est l'opacité)

    <preference name="BackgroundColor" value="0xff088c90" />
  6. Gérez vous-même votre position de défilement en ajoutant des événements de focus aux éléments d'entrée

    iscrollObj.scrollToElement(elm, transitionduration ... etc)

Pour Android, faites de même mais au lieu de cordova-plugin-webviewcolor , installez cordova-plugin-statusbar et cordova -plugin-navigationbar-color

Voici un code javascript utilisant ces plugins pour fonctionner à la fois sur iOS et Android:

function setStatusColor(colorCode) {
    //colorCode is smtg like '#427309';
    if (cordova.platformId == 'android') {
        StatusBar.backgroundColorByHexString(colorCode);
        NavigationBar.backgroundColorByHexString(colorCode);
    } else if (cordova.platformId == 'ios') {
        window.plugins.webviewcolor.change(colorCode);
    }
}
gdarcan
la source
1

Si vous installez des versions plus récentes de ionicglobalement, vous pouvez exécuter ionic cordova resourceset il générera toutes les images d'écran de démarrage pour vous avec les tailles correctes.

nébuleuse
la source
-1

Veuillez noter que cet article: https://medium.com/the-web-tub/supporting-iphone-x-for-mobile-web-cordova-app-using-onsen-ui-f17a4c272fcd a des tailles différentes de celles ci-dessus et cordova page du plugin:

Default@2x~iphone~anyany.png (= 1334x1334 = 667x667@2x)
Default@2x~iphone~comany.png (= 750x1334 = 375x667@2x)
Default@2x~iphone~comcom.png (= 750x750 = 375x375@2x)
Default@3x~iphone~anyany.png (= 2436x2436 = 812x812@3x)
Default@3x~iphone~anycom.png (= 2436x1242 = 812x414@3x)
Default@3x~iphone~comany.png (= 1242x2436 = 414x812@3x)
Default@2x~ipad~anyany.png (= 2732x2732 = 1366x1366@2x)
Default@2x~ipad~comany.png (= 1278x2732 = 639x1366@2x)

J'ai redimensionné les images comme ci-dessus et mis à jour la iosplate-forme et la cordova-plugin-splashscreendernière et le flash en écran blanc après la résolution d'un deuxième problème. Cependant, l'image de projection initiale a maintenant une bordure blanche en bas.

msmfsd
la source
1
Je peux confirmer le lancement de l'iPhone X sur le simulateur avec l' Default@3x~iphone~comany.png - 1242x2436image
msmfsd
À noter, les dimensions appropriées pour iPhone X sont les suivantes ... Portrait: 1125px × 2436px ... Paysage: 2436px × 1125px
Sterling Bourne