O aplicativo Cordova não é exibido corretamente no iPhone X (Simulador)

121

Ontem, testei meu aplicativo baseado em Cordova no iPhone X Simulator no Xcode 9.0 (9A235) e ele não parecia bom. Em primeiro lugar, em vez de preencher a área de tela cheia, havia uma área preta acima e abaixo do conteúdo do aplicativo. E pior, entre o conteúdo do aplicativo e o preto havia duas barras brancas.

Adicionar cordova-plugin-wkwebview-enginea renderização do Cordova usando o WKWebView (não o UIWebView) corrige as barras brancas. Por meu aplicativo não é migrado do UIWebView para o WKWebView devido a problemas de desempenho e vazamento de memória ao usar o cordova-plugin-wkwebview-engineque ocorre ao carregar imagens baixadas do Inapp Adquira conteúdo hospedado em uma tela HTML5 (o file://acesso direto pelo Webview não é possível devido a restrições de segurança no WKWebView, portanto os dados da imagem devem ser carregados via cordova-plugin-file).

Essas capturas de tela mostram um aplicativo de teste com um fundo azul definido no <body>. Acima e abaixo do UIWebView, você pode ver as barras brancas, mas não com o WKWebView:


(fonte: pbrd.co )


(fonte: pbrd.co )

As duas visualizações da Cordova na Web exibem as áreas pretas quando comparadas a um aplicativo nativo que preenche a área de tela inteira:

DaveAlden
fonte
Interessante com wkwebview. No meu jogo, eu não tinha largura total, mas também deslocado do centro. No uiwebview, ele mantinha o mesmo tamanho, mas se centra pelo menos.
agmcleod
Eu tive esse problema também, então eu fiz alguma solução com apenas css ver pt.stackoverflow.com/a/263460/55076
Igor Trindade
Eu também estou tendo esse problema. Apenas adicionar a <meta>tag ao meu arquivo cordova index.hml, como os outros listados abaixo, não está funcionando. Estou executando o Cordova 7x com o cordova-ios 4.5.4 - há mais alguma coisa que eu precise fazer?
Rolinger # 15/18

Respostas:

245

Encontrei a solução para as barras brancas aqui :

Defina viewport-fit=coverna <meta>tag viewport , ou seja:

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

As barras brancas no UIWebView desaparecem:

A solução para remover as áreas pretas (fornecido pelo @dpogue em um comentário abaixo) é usar imagens LaunchStoryboard com cordova-plugin-splashscreena substituir as imagens de lançamento legado, usados por Cordova por padrão. Para fazer isso, adicione o seguinte à plataforma iOS em 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>

Em seguida, crie as imagens com as seguintes dimensões em res/screen/ios(remova as existentes):

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

Depois que as barras pretas são removidas, há outra coisa diferente no iPhone X: a barra de status é maior que 20 px devido ao "entalhe", o que significa que qualquer conteúdo na parte superior do aplicativo Cordova será ocultado por ela. :

Em vez de codificar um preenchimento em pixels, você pode lidar com isso automaticamente em CSS usando as novas safe-area-inset-*constantes no iOS 11.

Nota: no iOS 11.0, a função para lidar com essas constantes foi chamada, constant()mas no iOS 11.2 a Apple a renomeou para env()( veja aqui ); portanto, para cobrir os dois casos, você precisa sobrecarregar a regra CSS com ambas e confiar no mecanismo de fallback CSS para aplicar o método apropriado:

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

O resultado é o desejado: o conteúdo do aplicativo cobre a tela inteira, mas não é obscurecido pelo "entalhe":

Eu criei um projeto de teste Cordova que ilustra as etapas acima: webview-test.zip

Notas:

Botões de rodapé

  • Se seu aplicativo tiver botões de rodapé (como o meu), você também precisará se inscrever safe-area-inset-bottompara evitar que eles se sobreponham ao botão Início virtual no iPhone X.
  • No meu caso, não pude aplicar isso, <body>pois o rodapé está absolutamente posicionado; portanto, era necessário aplicá-lo diretamente ao rodapé:

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

cordova-plugin-statusbar

  • O tamanho da barra de status foi alterado no iPhone X, portanto, versões mais antigas de cordova-plugin-statusbarexibição incorretamente no iPhone X
  • Mike Hartington criou essa solicitação de recebimento que aplica as alterações necessárias.
  • Isso foi mesclado na [email protected]versão, portanto, verifique se você está usando pelo menos esta versão para aplicar às inserções de área segura

tela de abertura

  • As restrições do storyboard do LaunchScreen foram alteradas no iOS 11 / iPhone X, o que significa que a tela inicial parece "saltar" na inicialização ao usar versões existentes do plug-in ( veja aqui ).
  • Isso foi capturado no relatório de bug CB-13505 , corrigido PR cordova-ios # 354 e lançado em [email protected], portanto, verifique se você está usando uma versão recente da cordova-iosplataforma.

orientação do dispositivo

  • Ao usar o UIWebView no iOS 11.0, girar de portrait> landscape> portrait faz com que o safe-area-insetnão seja reaplicado, fazendo com que o conteúdo seja obscurecido pelo entalhe novamente (conforme destacado por jms em um comentário abaixo).
  • Também acontece se o aplicativo for iniciado na paisagem e depois girado para o retrato
  • Isso não acontece ao usar o WKWebView via cordova-plugin-wkwebview-engine.
  • Relatório de radar: http://www.openradar.me/radar?id=5035192880201728
  • Atualização : isso parece ter sido corrigido no iOS 11.1

Para referência, esta é a edição original de Cordova que eu abri que captura isso: https://issues.apache.org/jira/browse/CB-13273

DaveAlden
fonte
3
Você tem algum problema ao girar a tela? Eu tenho tentado, mas depois de girar a tela, tudo está quebrado (área segura inserida- * não atualiza seus valores dependendo da orientação do dispositivo; e depois de girar retrato -> paisagem -> retrato novamente, os valores iniciais também são quebrados ) Poderia haver algum problema com o navegador apple / safari?
Juan Miguel S.
1
No meu caso, quando adicionei viewport-fit=covermeu aplicativo inteiro, apenas aparece uma tela branca em branco e nada mais. Estou usando o iOS11, Xcode9 no iPhone 7 Plus. Alguém experimentando comportamento semelhante?
Dimitri
1
@DaveAlden - parece que no 11.2 beta + eles caíram constantpara a envpalavra-chave - consulte também: webkit.org/blog/7929/designing-websites-for-iphone-x
Brent
1
onde você coloca o código css do corpo no seu aplicativo? Como em qual arquivo? Nada funciona para mim, estou usando o Ionic 3. #
Dimitri
2
Existe alguma atualização sobre o problema de rotação? Estou no iOS 12 e estou enfrentando o mesmo problema. Parece-me estranho que esse problema persista. / cc @jms
a - m
36

Para uma correção manual em um projeto cordova existente

As barras pretas

Adicione isso ao seu arquivo info.plist . A correção da imagem de inicialização é uma questão separada, por exemplo, como adicionar uma imagem de inicialização do iPhoneX

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

As barras brancas

Definir viewport-fit = cover na metatag

<meta name="viewport" content="initial-scale=1, width=device-width, height=device-height, viewport-fit=cover">
codificador
fonte
Obrigado! A alteração .plist tem o mesmo efeito que as alterações da resposta selecionada, mas MUITO MAIS rápido.
2Fwebd
O que cada uma dessas tarefas faz na altura e largura dos pixels em CSS? Meu aplicativo tem uma série de divs estreitas na parte superior (menus, etc) ... e depois calculo a altura restante do pixel para que o último DIV preencha o restante da tela. No momento, posso ver a barra branca inferior cobrindo parte desse DIV, mas também não posso dizer tudo - o que significa que o DIV ainda não está indo para a parte inferior da tela. E, por sua vez, meu aplicativo inicia abaixo da barra branca superior, portanto, nem está tentando usar o espaço superior.
Rolinger # 15/18
Eu usei UILaunchStoryboardNamee ele conseguiu remover as barras pretas. Mas minha tela inicial é expandida. Alguma razão para isso? A resposta aceite não está trabalhando para mim
Huiting
@coder Obrigado - mas adicionar o UILaunchStoryboardName ao plist me impede de enviar para a loja de aplicativos: ERRO ITMS-90705: "Iniciar storyboard não encontrado. Certifique-se de especificar o nome do arquivo do storyboard de lançamento sem uma extensão de nome de arquivo para a chave UILaunchStoryboardName no Info.plist ".
9788 Mattel Robertson
@Huiting encontrou alguma solução para o seu caso?
LMaker 04/04/19
16

Existem 3 etapas que você precisa executar

para problemas na barra de status do iOs 11 e no cabeçalho do iPhone X


1. Tampa de ajuste da janela de visualização

Adicione viewport-fit=coverà meta da sua viewport em<header>

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

Demonstração: https://jsfiddle.net/gq5pt509 (index.html)


  1. Adicione mais imagens de abertura ao seu config.xmlinterior<platform name="ios">

Não pule esta etapa , isso é necessário para obter o ajuste da tela para o trabalho do 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 -->

Demonstração: https://jsfiddle.net/mmy885q4 (config.xml)


  1. Corrija seu estilo no CSS

Use safe-area-inset-left, safe-area-inset-right, safe-area-inset-top, ousafe-area-inset-bottom

Exemplo: (use no seu 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});
}

Bônus: você pode adicionar classe de corpo como is-androidou is-iosno deviceready

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

Então você pode fazer algo assim em CSS

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

No meu caso, em que cada tela inicial foi projetada individualmente em vez de gerada automaticamente ou organizada em um formato de storyboard, tive que ficar com a configuração da tela Legacy Launch e adicionar imagens retrato e paisagem para direcionar as orientações iPhoneX 1125 × 2436 ao config.xml igual a:

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

Depois de adicioná-los ao config.xml ("viewport-fit = cover" já estava definido em index.hml), meu aplicativo criado com o Ionic Pro preenche a tela inteira em dispositivos iPhoneX.

TaeKwonJoe
fonte
senhor, mas na minha config.xml i já adicionou acima desta linha e viewport-fit = cobertura
Kapil soni
@Kapilsoni, pode ser um problema com o plug-in Cordova UIWebView, WKWebView, SplashScreen ou uma combinação dessas configurações. Além disso, você está segmentando o XCode 10 ou 11 em suas compilações?
TaeKwonJoe
senhor, estou visando o XCode 10?
Kapil soni
2

Correção para problema de rotação da tela do iPhone X / XS

No iPhone X / XS, uma rotação da tela fará com que a altura da barra de cabeçalho use um valor incorreto, porque o cálculo da área segura inserida * não refletia os novos valores a tempo da atualização da interface do usuário. Esse bug existe no UIWebView, mesmo no iOS 12. mais recente. Uma solução alternativa é inserir uma margem superior de 1px e revertê-la rapidamente, o que fará com que a área segura inset- * seja recalculada imediatamente. Uma correção um pouco feia, mas funciona se você precisar ficar com o UIWebView por um motivo ou outro.

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

O objetivo do código é fazer com que o document.body.style.marginTop mude levemente e depois o inverta. Não precisa necessariamente ser "1px". Você pode escolher um valor que não faça com que sua interface do usuário pisque, mas atinja seu objetivo.

YYL
fonte
O UIWebView foi privado no iOS8 ... duvido que algum dos erros existentes seja corrigido. Ao enviar aplicativos, a Apple avisa que isso será descontinuado em breve ... portanto, é hora de aliviar a dor e migrar para o WKWebView ...
Mozfet em
2

Estou desenvolvendo aplicativos cordova por 2 anos e passei semanas para resolver problemas relacionados (por exemplo: o webview rola quando o teclado é aberto). Aqui está uma solução testada e comprovada para iOS e Android

PS: Estou usando o iScroll para rolar o conteúdo

  1. Nunca use viewport-fit = cover na metatag de index.html, deixe o aplicativo fora da barra de status. O iOS manipulará a área adequada para todas as variantes do iPhone.
  2. No XCode, desmarque a opção Ocultar a barra de status e requer tela cheia. Não se esqueça de selecionar Iniciar arquivo de tela como CDVLaunchScreen.
  3. No config.xml, defina tela cheia como false
  4. Finalmente, (graças a Eddy Verbruggen pelos ótimos plugins), adicione seu plug -in cordova-plugin-webviewcolor para definir a barra de status e a cor de fundo da área inferior. Este plugin permitirá que você defina a cor desejada.
  5. Adicione abaixo ao config.xml (primeiro ff após x é opacidade)

    <preference name="BackgroundColor" value="0xff088c90" />
  6. Controle sua posição de rolagem adicionando eventos de foco aos elementos de entrada

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

Para o Android, faça o mesmo, mas em vez de cordova-plugin-webviewcolor , instale cordova-plugin-statusbar e cordova-plugin-navigationbar-color

Aqui está um código javascript usando esses plugins para funcionar no ios e no 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
fonte
1

Se você instalar versões mais recentes do ionicmundo, poderá executar ionic cordova resourcese isso gerará todas as imagens da tela de abertura para você, juntamente com os tamanhos corretos.

nebulr
fonte
-1

Observe que este artigo: https://medium.com/the-web-tub/supporting-iphone-x-for-mobile-web-cordova-app-using-onsen-ui-f17a4c272fcd possui tamanhos diferentes do que acima e cordova página de plug-in:

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)

Redimensionei as imagens como acima e atualizei a iosplataforma e cordova-plugin-splashscreena mais recente e o flash para a tela branca após a correção de um segundo problema. No entanto, a imagem spash inicial tem uma borda branca na parte inferior agora.

msmfsd
fonte
1
Posso confirmar o iPhone X em lançamentos simulador com Default@3x~iphone~comany.png - 1242x2436imagem
msmfsd
De nota, as dimensões adequadas para iPhone X são os seguintes ... Retrato: 1125px × 2436px ... Paisagem: 2436px × 1125px
Sterling Bourne