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:


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 cordova-plugin-statusbar@2.3.0wydania, 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 cordova-ios@4.5.4, 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


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

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
}

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.


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.


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);
    }
}

1

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


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


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.