L'app Cordova non viene visualizzata correttamente su iPhone X (simulatore)


121

Ho testato la mia app basata su Cordova ieri su iPhone X Simulator in Xcode 9.0 (9A235) e non sembrava buona. In primo luogo, invece di riempire l'area a schermo intero, c'era un'area nera sopra e sotto il contenuto dell'app. E peggio, tra il contenuto dell'app e il nero c'erano due barre bianche.

L'aggiunta in cordova-plugin-wkwebview-enginemodo che Cordova esegua il rendering utilizzando WKWebView (non UIWebView) risolve le barre bianche. Dalla mia app non viene migrato da UIWebView a WKWebView a causa di problemi di prestazioni e perdita di memoria durante l'utilizzo cordova-plugin-wkwebview-engineche si verificano durante il caricamento di immagini scaricate da Inapp Purchase contenuto ospitato in una tela HTML5 (l' file://accesso diretto da Webview non è possibile a causa di limitazioni di sicurezza in WKWebView quindi i dati dell'immagine devono essere caricati tramite cordova-plugin-file).

Questi screenshot mostrano un'app di prova con uno sfondo blu impostato su <body>. Sopra e sotto UIWebView, puoi vedere le barre bianche, ma non con WKWebView:


(fonte: pbrd.co )


(fonte: pbrd.co )

Entrambe le visualizzazioni Web di Cordova mostrano le aree nere rispetto a un'app nativa che riempie l'area a schermo intero:


Interessante con wkwebview. Nel mio gioco, non lo avevo a tutta larghezza, ma anche spostato dal centro. In uiwebview ha mantenuto le stesse dimensioni, ma almeno si centra.
agmcleod

Anch'io ho avuto questo problema, quindi ho fatto qualche soluzione alternativa con solo CSS vedi pt.stackoverflow.com/a/263460/55076
Igor Trindade

Anch'io sto avendo questo problema. Basta aggiungere il <meta>tag al mio file cordova index.hml poiché gli altri elencati di seguito non funzionano. Sto eseguendo Cordova 7x con cordova-ios 4.5.4 - c'è qualcos'altro che devo fare?
Rolinger

Risposte:


246

Ho trovato la soluzione alle barre bianche qui :

Impostato viewport-fit=coversul <meta>tag viewport , ovvero:

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

Le barre bianche in UIWebView quindi scompaiono:

La soluzione per rimuovere le aree nere (fornita da @dpogue in un commento qui sotto) è usare le immagini LaunchStoryboard con cordova-plugin-splashscreenper sostituire le immagini di avvio legacy, utilizzate da Cordova per impostazione predefinita. Per fare ciò, aggiungi quanto segue alla piattaforma iOS 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>

Quindi crea le immagini con le seguenti dimensioni in res/screen/ios(rimuovi quelle esistenti):

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

Una volta rimosse le barre nere, c'è un'altra cosa che è diversa nell'iPhone X da affrontare: la barra di stato è più grande di 20px a causa della "tacca", il che significa che qualsiasi contenuto nella parte superiore della tua app Cordova sarà oscurato da essa :

Anziché codificare un riempimento in pixel, puoi gestirlo automaticamente in CSS utilizzando le nuove safe-area-inset-*costanti in iOS 11.

Nota: in iOS 11.0 è stata chiamata la funzione per gestire queste costanti constant()ma in iOS 11.2 Apple l'ha rinominata in env()( vedi qui ), quindi per coprire entrambi i casi è necessario sovraccaricare la regola CSS con entrambe e fare affidamento sul meccanismo di fallback CSS per applicare il quello appropriato:

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

Il risultato è quindi quello desiderato: il contenuto dell'app copre tutto lo schermo, ma non è oscurato dal "notch":

Ho creato un progetto di test Cordova che illustra i passaggi precedenti: webview-test.zip

Appunti:

Pulsanti piè di pagina

  • Se la tua app ha pulsanti a piè di pagina (come la mia), dovrai anche fare domanda safe-area-inset-bottomper evitare che vengano sovrapposti dal pulsante Home virtuale su iPhone X.
  • Nel mio caso, non potevo applicarlo <body>perché il piè di pagina è posizionato in modo assoluto, quindi dovevo applicarlo direttamente al piè di pagina:

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

Cordova-plugin-statusbar

  • La dimensione della barra di stato è cambiata su iPhone X, quindi le versioni precedenti della cordova-plugin-statusbarvisualizzazione non vengono visualizzate correttamente su iPhone X.
  • Mike Hartington ha creato questa richiesta pull che applica le modifiche necessarie.
  • Questo è stato unito alla cordova-plugin-statusbar@2.3.0versione, quindi assicurati di utilizzare almeno questa versione da applicare agli inserti dell'area sicura

splashscreen

  • I vincoli dello storyboard di LaunchScreen sono cambiati su iOS 11 / iPhone X, il che significa che la schermata iniziale sembrava "saltare" all'avvio quando si utilizzano versioni esistenti del plug-in ( vedere qui ).
  • Questo è stato catturato nel bug report CB-13505 , corretto PR cordova-ios # 354 e rilasciato in cordova-ios@4.5.4, quindi assicurati di utilizzare una versione recente della cordova-iospiattaforma.

orientamento del dispositivo

  • Quando si utilizza UIWebView su iOS 11.0, la rotazione da verticale> orizzontale> verticale fa sì che il safe-area-insetnon venga riapplicato, facendo sì che il contenuto venga nuovamente oscurato dalla tacca (come evidenziato da jms in un commento sotto).
  • Succede anche se l'app viene avviata in orizzontale e ruotata in verticale
  • Questo non accade quando si utilizza WKWebView tramite cordova-plugin-wkwebview-engine.
  • Rapporto radar: http://www.openradar.me/radar?id=5035192880201728
  • Aggiornamento : questo sembra essere stato risolto in iOS 11.1

Per riferimento, questo è il numero originale di Cordova che ho aperto che cattura questo: https://issues.apache.org/jira/browse/CB-13273


3
Hai problemi quando ruoti lo schermo? Ho provato, ma dopo aver ruotato lo schermo, tutto è rotto (safe-area-inset- * non aggiorna i loro valori a seconda dell'orientamento del dispositivo; e dopo aver ruotato di nuovo verticale -> orizzontale -> verticale, anche i valori iniziali sono interrotti ). Potrebbe esserci qualche problema con il browser Apple / Safari?
Juan Miguel S.

1
Nel mio caso, quando ho aggiunto viewport-fit=covertutta la mia app mostra solo una schermata bianca vuota e nient'altro. Sto usando iOS11, Xcode9 su iPhone 7 Plus. Qualcuno ha avuto un comportamento simile?
Dimitri

1
@DaveAlden - sembra che nel 11.2 beta + hanno lasciato cadere constantper envparola chiave - vedi anche: webkit.org/blog/7929/designing-websites-for-iphone-x
Brent

1
dove metti il ​​codice CSS del corpo nella tua App? Come in quale file? Niente funziona per me, sto usando Ionic 3.
Dimitri

2
C'è qualche aggiornamento riguardo al problema di rotazione? Sono su iOS 12 e riscontro lo stesso problema. Mi sembra strano che questo problema persista. / cc @jms
a - m

36

Per una correzione manuale a un progetto cordova esistente

Le barre nere

Aggiungilo al tuo file info.plist . La correzione dell'immagine di avvio è un problema separato, ad esempio Come aggiungere l'immagine di avvio di iPhoneX

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

Le barre bianche

Imposta viewport-fit = cover nel meta tag

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

Grazie! La modifica .plist ha lo stesso effetto delle modifiche dalla risposta selezionata, ma MOLTO più veloce.
2Fwebd

Che cosa fa ciascuna di queste attività per l'altezza e la larghezza dei pixel CSS? La mia app ha una serie di div stretti in alto (menu, ecc.) ... e poi calcolo l'altezza dei pixel rimanenti per fare in modo che l'ultimo DIV riempia il resto dello schermo. In questo momento posso vedere la barra bianca inferiore che copre parte di quel DIV, ma posso anche dirlo non tutto - il che significa che il DIV non sta ancora andando nella parte inferiore dello schermo. E a sua volta, la mia app inizia sotto la barra bianca superiore, quindi non sta nemmeno cercando di utilizzare lo spazio superiore.
Rolinger

Ho usato UILaunchStoryboardNameed è riuscito a rimuovere le barre nere. Ma la mia schermata iniziale viene espansa. Qualche motivo per cui? La risposta accettata non funziona per me
Huiting

@coder Grazie - ma l'aggiunta di UILaunchStoryboardName al plist mi impedisce di inviare all'app store: ERRORE ITMS-90705: "Avvio storyboard non trovato. Assicurati di specificare il nome del file dello storyboard di avvio senza un'estensione del nome file per la chiave UILaunchStoryboardName nella Info.plist. "
Matt Roberts

@Huiting hai trovato una soluzione per il tuo caso?
LMaker

16

Ci sono 3 passaggi che devi fare

per problemi con la barra di stato di iOS 11 e con l'intestazione di iPhone X.


1. Viewport fit copertura

Aggiungi viewport-fit=coveral meta del tuo viewport in<header>

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

Demo: https://jsfiddle.net/gq5pt509 (index.html)


  1. Aggiungi più immagini splash al tuo config.xmlinterno<platform name="ios">

Dont saltare questo passaggio , questo ha richiesto per ottenere la misura dello schermo per iPhone X lavoro

<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 -->

Demo: https://jsfiddle.net/mmy885q4 (config.xml)


  1. Correggi il tuo stile su CSS

Utilizzare safe-area-inset-left, safe-area-inset-right, safe-area-inset-toposafe-area-inset-bottom

Esempio: (Usa nel tuo caso!)

#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: puoi aggiungere la classe del corpo come is-androido is-iossu deviceready

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

Quindi puoi fare qualcosa di simile su CSS

.is-ios #header {
 // Properties
}

5

Nel mio caso in cui ogni schermata iniziale è stata progettata individualmente anziché generata automaticamente o disposta in un formato storyboard, ho dovuto attenermi alla configurazione della schermata di avvio legacy e aggiungere immagini verticali e orizzontali per indirizzare gli orientamenti di iPhoneX 1125 × 2436 al config.xml così:

<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" />

Dopo averli aggiunti a config.xml ("viewport-fit = cover" era già impostato in index.hml) la mia app costruita con Ionic Pro riempie l'intero schermo sui dispositivi iPhoneX.


signore ma nel mio config.xml ho già aggiunto sopra questa riga e viewport-fit = cover
Kapil soni

@Kapilsoni quindi potrebbe essere un problema con Cordova UIWebView, WKWebView, plug-in SplashScreen o una combinazione di queste configurazioni. Inoltre, stai prendendo di mira XCode 10 o 11 nelle tue build?
TaeKwonJoe

signore, sto prendendo di mira XCode 10?
Kapil soni


2

Risolto il problema di rotazione dello schermo di iPhone X / XS

Su iPhone X / XS, una rotazione dello schermo farà sì che l'altezza della barra dell'intestazione utilizzi un valore errato, perché il calcolo di safe-area-inset- * non rifletteva i nuovi valori in tempo per l'aggiornamento dell'interfaccia utente. Questo bug esiste in UIWebView anche nell'ultimo iOS 12. Una soluzione alternativa consiste nell'inserire un margine superiore di 1 px e quindi invertirlo rapidamente, il che attiverà il ricalcolo immediato dell'area sicura. Una soluzione un po 'brutta ma funziona se devi rimanere con UIWebView per un motivo o per l'altro.

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

Lo scopo del codice è far cambiare leggermente il documento.body.style.marginTop e quindi invertirlo. Non deve essere necessariamente "1px". Puoi scegliere un valore che non causi lo sfarfallio dell'interfaccia utente ma che raggiunga il suo scopo.


UIWebView è stato deprecato in iOS8 ... Dubito che qualcuno dei bug esistenti verrà risolto. Apple avverte durante il caricamento delle app che questo verrà interrotto a breve ... quindi è tempo di prendersi il dolore e migrare a WKWebView ...
Mozfet

2

Sto sviluppando app cordova da 2 anni e ho passato settimane a risolvere problemi correlati (ad esempio: webview scorre quando la tastiera è aperta). Ecco una soluzione testata e comprovata sia per ios che per Android

PS: sto usando iScroll per lo scorrimento dei contenuti

  1. Non utilizzare mai viewport-fit = cover nel meta tag di index.html, lasciare l'app fuori dalla barra di stato. iOS gestirà l'area corretta per tutte le varianti di iPhone.
  2. In XCode deseleziona Nascondi barra di stato e richiede lo schermo intero e non dimenticare di selezionare Avvia file schermo come CDVLaunchScreen
  3. In config.xml imposta lo schermo intero come false
  4. Infine, (grazie a Eddy Verbruggen per gli ottimi plugin) aggiungi il suo plugin cordova-plugin-webviewcolor per impostare la barra di stato e il colore di sfondo dell'area inferiore. Questo plugin ti permetterà di impostare qualsiasi colore tu voglia.
  5. Aggiungi sotto a config.xml (il primo ff dopo x è l'opacità)

    <preference name="BackgroundColor" value="0xff088c90" />
  6. Gestisci tu stesso la posizione di scorrimento aggiungendo eventi di attivazione agli elementi di input

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

Per Android, fai lo stesso ma invece di cordova-plugin-webviewcolor , installa cordova-plugin-statusbar e cordova-plugin-navigationbar-color

Ecco un codice javascript che utilizza questi plugin per funzionare sia su iOS che su 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);
    }
}

1

Se installi versioni più recenti di ionicglobalmente, puoi eseguire ionic cordova resourcese genererà tutte le immagini della schermata iniziale insieme alle dimensioni corrette.


-1

Si prega di notare che questo articolo: https://medium.com/the-web-tub/supporting-iphone-x-for-mobile-web-cordova-app-using-onsen-ui-f17a4c272fcd ha dimensioni diverse da quelle sopra e cordova pagina 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)

Ho ridimensionato le immagini come sopra e aggiornato la iospiattaforma e cordova-plugin-splashscreenall'ultimo e il flash su schermo bianco dopo che è stato risolto un secondo problema. Tuttavia, l'immagine iniziale di spash ha ora un bordo bianco in basso.


1
Posso confermare che l'iPhone X sul simulatore si avvia con l' Default@3x~iphone~comany.png - 1242x2436immagine
msmfsd

Da notare che le dimensioni corrette per iPhone X sono le seguenti ... Verticale: 1125px × 2436px ... Orizzontale: 2436px × 1125px
Sterling Bourne
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.