Aplikacja Cordova nie wyświetla się poprawnie na telefonie iPhone X (symulator)

121

Przetestowałem wczoraj moją aplikację opartą na Cordovie na symulatorze iPhone'a X w Xcode 9.0 (9A235) i nie wyglądała dobrze. Po pierwsze, zamiast wypełniać cały obszar ekranu, nad i pod zawartością aplikacji był czarny obszar. Co gorsza, między zawartością aplikacji a czernią były dwa białe paski.

Dodanie do cordova-plugin-wkwebview-enginerenderowania Cordova przy użyciu WKWebView (nie UIWebView) naprawia białe paski. Moja aplikacja nie jest migrowana z UIWebView do WKWebView z powodu problemów z wydajnością i wyciekiem pamięci podczas używania, cordova-plugin-wkwebview-enginektóre występują podczas ładowania obrazów pobranych z hostowanej zawartości Inapp Purchase do kanwy HTML5 (bezpośredni file://dostęp przez Webview nie jest możliwy z powodu ograniczeń bezpieczeństwa w WKWebView, więc dane obrazu należy załadować za pośrednictwem cordova-plugin-file).

Te zrzuty ekranu pokazują aplikację testową z niebieskim tłem ustawionym na <body>. Powyżej i poniżej UIWebView widać białe paski, ale nie w przypadku WKWebView:


(źródło: pbrd.co )


(źródło: pbrd.co )

Oba widoki internetowe Cordova wyświetlają czarne obszary w porównaniu z natywną aplikacją, która wypełnia cały obszar ekranu:

DaveAlden
źródło
Ciekawe z wkwebview. W mojej grze nie miałem pełnej szerokości, ale także odsunięto od środka. W uiwebview zachował ten sam rozmiar, ale przynajmniej skupia się na sobie.
agmcleod
Miałem też ten problem, więc obejrzałem
Igor Trindade,
Ja też mam ten problem. Samo dodanie <meta>tagu do mojego pliku cordova index.hml, ponieważ inne wymienione poniżej nie działają. Używam Cordova 7x z Cordova-ios 4.5.4 - czy jest jeszcze coś, co muszę zrobić?
rolinger

Odpowiedzi:

246

Rozwiązanie białych pasków znalazłem tutaj :

Ustaw viewport-fit=coverna <meta>etykiecie rzutni , tj .:

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

Następnie białe paski w UIWebView znikają:

Rozwiązaniem umożliwiającym usunięcie czarnych obszarów (dostarczonych przez @dpogue w komentarzu poniżej) jest użycie obrazów LaunchStoryboard w cordova-plugin-splashscreencelu zastąpienia starszych obrazów uruchamiania, używanych domyślnie przez Cordovę . Aby to zrobić, dodaj następujące elementy do platformy iOS w 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>

Następnie utwórz obrazy o następujących wymiarach res/screen/ios(usuń wszystkie istniejące):

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

Po usunięciu czarnych pasków jest jeszcze jedna rzecz, która różni się w iPhonie X do rozwiązania: pasek stanu jest większy niż 20 pikseli ze względu na „wycięcie”, co oznacza, że ​​każda zawartość w górnej części aplikacji Cordova będzie zasłonięta. :

Zamiast na safe-area-inset-*stałe kodować dopełnienie w pikselach, możesz obsłużyć to automatycznie w CSS, używając nowych stałych w iOS 11.

Uwaga: w iOS 11.0 funkcja obsługująca te stałe została wywołana, constant()ale w iOS 11.2 Apple zmienił jej nazwę na env()( patrz tutaj ), dlatego aby objąć oba przypadki, musisz przeciążać regułę CSS oboma i polegać na mechanizmie rezerwowym CSS, aby zastosować odpowiedni:

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

Wynik jest zgodny z oczekiwaniami: zawartość aplikacji obejmuje cały ekran, ale nie jest zasłonięta „wycięciem”:

Stworzyłem projekt testowy Cordova, który ilustruje powyższe kroki: webview-test.zip

Uwagi:

Przyciski stopki

  • Jeśli Twoja aplikacja ma przyciski stopki (tak jak moja), musisz również zastosować, safe-area-inset-bottomaby uniknąć ich nakładania się na wirtualny przycisk Home na iPhonie X.
  • W moim przypadku nie mogłem tego zastosować, <body>ponieważ stopka jest absolutnie ustawiona, więc musiałem zastosować ją bezpośrednio do stopki:

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

cordova-plugin-statusbar

  • Rozmiar paska stanu zmienił się na iPhonie X, więc starsze wersje cordova-plugin-statusbarwyświetlają się nieprawidłowo na iPhonie X.
  • Mike Hartington utworzył to żądanie ściągnięcia, które wprowadza niezbędne zmiany.
  • To zostało włączone do [email protected]wydania, więc upewnij się, że używasz przynajmniej tej wersji do zastosowania do wstawek do bezpiecznego obszaru

ekran powitalny

  • Ograniczenia dotyczące scenorysu LaunchScreen uległy zmianie na iOS 11 / iPhone X, co oznacza, że ​​ekran powitalny „przeskakuje” podczas uruchamiania podczas korzystania z istniejących wersji wtyczki ( patrz tutaj ).
  • Zostało to uchwycone w raporcie o błędzie CB-13505 , naprawiono PR cordova-ios # 354 i wydano w [email protected], więc upewnij się, że używasz najnowszej wersji cordova-iosplatformy.

orientacja urządzenia

  • Podczas korzystania z UIWebView w systemie iOS 11.0 obrót z pozycji portret> krajobraz> portret powoduje, że safe-area-insetnie są one ponownie stosowane, co powoduje ponowne zasłonięcie zawartości przez wycięcie (co zostało podkreślone przez jms w komentarzu poniżej).
  • Dzieje się również, jeśli aplikacja zostanie uruchomiona w orientacji poziomej, a następnie obrócona do pionu
  • Nie dzieje się tak, gdy używasz WKWebView za pośrednictwem cordova-plugin-wkwebview-engine.
  • Raport radarowy: http://www.openradar.me/radar?id=5035192880201728
  • Aktualizacja : wydaje się, że zostało to naprawione w iOS 11.1

Dla porównania, jest to oryginalny numer Cordova, który otworzyłem, który zawiera to: https://issues.apache.org/jira/browse/CB-13273

DaveAlden
źródło
3
Czy masz jakieś problemy podczas obracania ekranu? Próbowałem, ale po obróceniu ekranu wszystko jest zepsute (safe-area-inset- * nie aktualizuje swoich wartości w zależności od orientacji urządzenia; a po obróceniu portret -> krajobraz -> portret ponownie, początkowe wartości też są zepsute ). Czy to może być jakiś problem z przeglądarką Apple / Safari?
Juan Miguel S.
1
W moim przypadku, gdy dodałem viewport-fit=covercałą moją aplikację, wyświetla się tylko pusty biały ekran i nic więcej. Używam iOS11, Xcode9 na iPhonie 7 Plus. Czy ktoś doświadcza podobnego zachowania?
Dimitri
1
@DaveAlden - wygląda, że w 11.2 beta + oni spadła constantdo envhasła - patrz też: webkit.org/blog/7929/designing-websites-for-iphone-x
Brent
1
gdzie umieszczasz kod css body w swojej aplikacji? Jak w którym pliku? Dla mnie nic nie działa, używam Ionic 3.
Dimitri,
2
Czy jest jakaś aktualizacja dotycząca problemu z rotacją? Mam system iOS 12 i mam ten sam problem. Dziwnie mi się wydaje, że ten problem nadal występuje. / cc @jms
a - m
36

Do ręcznej naprawy istniejącego projektu Cordova

Czarne paski

Dodaj to do swojego pliku info.plist . Naprawianie obrazu startowego to osobny problem, np. Jak dodać obraz startowy iPhoneX

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

Białe paski

Ustaw viewport-fit = cover w metatagu

<meta name="viewport" content="initial-scale=1, width=device-width, height=device-height, viewport-fit=cover">
koder
źródło
Dzięki! Zmiana .plist ma taki sam efekt jak zmiany z wybranej odpowiedzi, ale DUŻO szybciej.
2Fwebd
Jak każde z tych zadań wpływa na wysokość i szerokość pikseli CSS? Moja aplikacja ma u góry serię wąskich elementów div (menu itp.) ... a następnie obliczam pozostałą wysokość piksela, aby ostatnia DIV wypełniła resztę ekranu. W tej chwili widzę, że dolny biały pasek obejmuje część tego DIV, ale mogę też powiedzieć nie wszystko - co oznacza, że ​​DIV nadal nie schodzi na dół ekranu. Z kolei moja aplikacja zaczyna się poniżej górnego białego paska, więc nawet nie próbuje użyć górnej przestrzeni.
rolinger
Użyłem UILaunchStoryboardNamei udało mi się usunąć czarne paski. Ale mój ekran powitalny zostaje rozszerzony. Jakiś powód dlaczego? Przyjęta odpowiedź nie działa dla mnie
Huiting
@coder Dzięki - ale dodanie UILaunchStoryboardName do plist uniemożliwia mi przesłanie do sklepu z aplikacjami: BŁĄD ITMS-90705: „Nie znaleziono uruchomienia storyboardu. Upewnij się, że podałeś nazwę pliku scenariusza uruchamiania bez rozszerzenia nazwy pliku dla klucza UILaunchStoryboardName w Info.plist. ”
Matt Roberts,
@Huiting Czy znalazłeś jakieś rozwiązanie w swojej sprawie?
LMaker
16

Musisz wykonać 3 kroki

dla problemów z paskiem stanu iOs 11 i nagłówkiem iPhone'a X.


1. Pokrywa dopasowana do rzutni

Dodaj viewport-fit=coverdo meta widoku w<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. Dodaj więcej obrazów powitalnych do swojego config.xmlwnętrza<platform name="ios">

Nie pomijaj tego kroku , jest to wymagane do dopasowania ekranu do pracy iPhone'a 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 -->

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


  1. Napraw swój styl w CSS

Użyj safe-area-inset-left, safe-area-inset-right, safe-area-inset-toplubsafe-area-inset-bottom

Przykład: (Użyj w twoim przypadku!)

#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: możesz dodać klasę ciała jak is-androidlub is-iosna urządzeniu

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

Możesz więc zrobić coś takiego w CSS

.is-ios #header {
 // Properties
}
l2aelba
źródło
5

W moim przypadku, gdy każdy ekran powitalny był indywidualnie projektowany zamiast generowany automatycznie lub układany w formacie storyboardu, musiałem trzymać się mojej konfiguracji ekranu Legacy Launch i dodać obrazy pionowe i poziome, aby kierować orientacje iPhoneX 1125 × 2436 do config.xml tak jak:

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

Po dodaniu ich do config.xml („viewport-fit = cover” było już ustawione w index.hml) moja aplikacja zbudowana w Ionic Pro wypełnia cały ekran na urządzeniach iPhoneX.

TaeKwonJoe
źródło
proszę pana, ale w moim config.xml dodałem już powyżej tej linii i viewport-fit = cover
Kapil soni
@Kapilsoni może to być problem z wtyczką Cordova UIWebView, WKWebView, SplashScreen lub kombinacją tych konfiguracji. Czy celujesz w XCode 10 lub 11 w swoich kompilacjach?
TaeKwonJoe
sir, celuję w XCode 10?
Kapil soni
2

Naprawiono problem z obracaniem ekranu iPhone'a X / XS

Na iPhonie X / XS obrót ekranu spowoduje, że wysokość paska nagłówka będzie miała nieprawidłową wartość, ponieważ obliczenie safe-area-inset- * nie odzwierciedlało nowych wartości w czasie odświeżania interfejsu użytkownika. Ten błąd występuje w UIWebView nawet w najnowszym iOS 12. Obejście polega na wstawieniu górnego marginesu o wielkości 1 piksela, a następnie jego szybkim odwróceniu, co spowoduje natychmiastowe ponowne obliczenie wstawienia bezpiecznego obszaru *. Trochę brzydka poprawka, ale działa, jeśli musisz pozostać przy UIWebView z jakiegoś powodu.

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

Celem kodu jest spowodowanie niewielkiej zmiany w document.body.style.marginTop, a następnie odwrócenie tego. Nie musi to być koniecznie „1 piksel”. Możesz wybrać wartość, która nie powoduje migotania interfejsu użytkownika, ale spełnia swój cel.

YYL
źródło
UIWebView został pozbawiony w iOS8 ... Wątpię, czy któryś z istniejących błędów zostanie naprawiony. Apple ostrzega podczas przesyłania aplikacji, że wkrótce zostanie to przerwane ... więc czas, aby wziąć ból i przejść do WKWebView ...
Mozfet
2

Tworzę aplikacje Cordova od 2 lat i spędziłem tygodnie na rozwiązywaniu związanych z nimi problemów (np. Przewijanie widoku internetowego po otwarciu klawiatury). Oto przetestowane i sprawdzone rozwiązanie dla systemów iOS i Android

PS: Używam iScroll do przewijania zawartości

  1. Nigdy nie używaj viewport-fit = cover w metatagu index.html, pozostaw aplikację poza paskiem stanu. iOS obsłuży odpowiedni obszar dla wszystkich wariantów iPhone'a.
  2. W XCode odznacz ukryj pasek stanu i wymaga pełnego ekranu i nie zapomnij wybrać Uruchom plik ekranu jako CDVLaunchScreen
  3. W config.xml ustaw pełny ekran jako fałsz
  4. Na koniec (dzięki Eddy'emu Verbruggenowi za świetne wtyczki) dodaj jego wtyczkę cordova-plugin-webviewcolor aby ustawić stanu i kolor tła dolnego obszaru. Ta wtyczka pozwoli ci ustawić dowolny kolor.
  5. Dodaj poniżej do config.xml (pierwszy ff po x oznacza krycie)

    <preference name="BackgroundColor" value="0xff088c90" />
  6. Obsługuj samodzielnie pozycję przewijania, dodając zdarzenia aktywności do elementów wejściowych

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

W przypadku Androida zrób to samo, ale zamiast cordova-plugin-webviewcolor zainstaluj cordova-plugin-statusbar i cordova-plugin-navigationbar-color

Oto kod javascript wykorzystujący te wtyczki do pracy zarówno na iOS, jak i Androidzie:

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
źródło
1

Jeśli zainstalujesz nowsze wersje ionicglobalnie, możesz uruchomić ionic cordova resourcesi wygeneruje dla Ciebie wszystkie obrazy powitalne wraz z odpowiednimi rozmiarami.

nebulr
źródło
-1

Zwróć uwagę, że ten artykuł: https://medium.com/the-web-tub/supporting-iphone-x-for-mobile-web-cordova-app-using-onsen-ui-f17a4c272fcd ma inne rozmiary niż powyżej i cordova strona wtyczki:

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)

Zmieniłem rozmiar obrazów jak powyżej i zaktualizowałem iosplatformę i cordova-plugin-splashscreendo najnowszej, a flashowanie do białego ekranu po naprawieniu drugiego problemu. Jednak początkowy obraz spash ma teraz białą ramkę na dole.

msmfsd
źródło
1
Mogę potwierdzić, że iPhone X na symulatorze uruchamia się z Default@3x~iphone~comany.png - 1242x2436obrazem
msmfsd
Warto zauważyć, że odpowiednie wymiary dla iPhone'a X są następujące ... Portret: 1125px × 2436px ... Landscape: 2436px × 1125px
Sterling Bourne