Приложение Cordova некорректно отображается на iPhone X (Симулятор)


121

Вчера я протестировал свое приложение на основе Cordova на iPhone X Simulator в Xcode 9.0 (9A235), и оно выглядело не очень хорошо. Во-первых, вместо заполнения всей области экрана над и под содержимым приложения была черная область. И что еще хуже, между содержимым приложения и черным было две белых полосы.

Добавление cordova-plugin-wkwebview-engineтак, чтобы Cordova визуализировала с использованием WKWebView (не UIWebView), исправляет белые полосы. Мое приложение не переносится из UIWebView в WKWebView из-за проблем с производительностью и утечкой памяти при использовании, cordova-plugin-wkwebview-engineкоторые возникают при загрузке изображений, загруженных из Inapp. Покупка размещенного контента в холст HTML5 (прямой file://доступ через Webview невозможен из-за ограничений безопасности в WKWebView, поэтому данные изображения должны быть загружены через cordova-plugin-file).

На этих снимках экрана показано тестовое приложение с синим фоном, установленным на <body>. Выше и ниже UIWebView вы можете видеть белые полосы, но не с WKWebView:


(источник: pbrd.co )


(источник: pbrd.co )

Оба Cordova Webviews показывают черные области по сравнению с собственным приложением, которое заполняет всю область экрана:


Интересно с wkwebview. В моей игре он был не на всю ширину, но и со смещением от центра. В uiwebview он сохранил тот же размер, но, по крайней мере, центрируется.
agmcleod

У меня тоже была эта проблема, поэтому я нашел
Игорь Триндаде

У меня тоже есть эта проблема. Просто добавление <meta>тега в мой файл cordova index.hml, поскольку другие, перечисленные ниже, не работают. Я использую Cordova 7x с cordova-ios 4.5.4 - что еще мне нужно сделать?
Rolinger

Ответы:


246

Я нашел решение для белых полос здесь :

Устанавливается viewport-fit=coverв <meta>теге области просмотра , то есть:

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

После этого белые полосы в UIWebView исчезнут:

Решение для удаления черных областей (предоставленное @dpogue в комментарии ниже) заключается в использовании изображений LaunchStoryboard с cordova-plugin-splashscreenзаменой устаревших изображений запуска, используемых Cordova по умолчанию. Для этого добавьте на платформу iOS следующее 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>

Затем создайте изображения со следующими размерами res/screen/ios(удалите все существующие):

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

После удаления черных полос в iPhone X есть еще одна особенность, которую нужно решить: строка состояния больше 20 пикселей из-за «выемки», что означает, что любой контент в верхней части вашего приложения Cordova будет скрыт им. :

Вместо того, чтобы жестко кодировать отступы в пикселях, вы можете обрабатывать это автоматически в CSS, используя новые safe-area-inset-*константы в iOS 11.

Примечание: в iOS 11.0 была вызвана функция для обработки этих констант, constant()но в iOS 11.2 Apple переименовала ее в env()( см. Здесь ), поэтому, чтобы охватить оба случая, вам нужно перегрузить правило CSS обоими и полагаться на резервный механизм CSS для применения подходящий:

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

Результат будет таким, каким вы хотели: содержимое приложения занимает весь экран, но не закрывается «выемкой»:

Я создал тестовый проект Cordova, который иллюстрирует вышеуказанные шаги: webview-test.zip

Ноты:

Кнопки нижнего колонтитула

  • Если в вашем приложении есть кнопки нижнего колонтитула (как у меня), вам также необходимо применить их, safe-area-inset-bottomчтобы избежать их перекрытия виртуальной кнопкой «Домой» на iPhone X.
  • В моем случае я не мог применить это к, <body>поскольку нижний колонтитул абсолютно позиционирован, поэтому мне нужно было применить его непосредственно к нижнему колонтитулу:

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

Cordova-плагин-статусной

  • Размер строки состояния изменился на iPhone X, поэтому старые версии cordova-plugin-statusbarнекорректно отображаются на iPhone X
  • Майк Хартингтон создал этот запрос на перенос, который применяет необходимые изменения.
  • Это было объединено с cordova-plugin-statusbar@2.3.0выпуском, поэтому убедитесь, что вы используете хотя бы эту версию для применения к вставкам безопасной области.

заставка

  • Ограничения раскадровки LaunchScreen изменились в iOS 11 / iPhone X, что означает, что заставка "прыгала" при запуске при использовании существующих версий плагина ( см. Здесь ).
  • Это было зафиксировано в отчете об ошибке CB-13505 , исправлено PR cordova-ios # 354 и выпущено cordova-ios@4.5.4, поэтому убедитесь, что вы используете последнюю версию cordova-iosплатформы.

ориентация устройства

  • При использовании UIWebView в iOS 11.0 поворот из портрета> пейзажа> портрета не приводит safe-area-insetк повторному применению, в результате чего контент снова скрывается за выемкой (как выделено jms в комментарии ниже).
  • Также происходит, если приложение запущено в альбомной ориентации, а затем повернуто в портретную.
  • Этого не происходит при использовании WKWebView через cordova-plugin-wkwebview-engine.
  • Отчет радара: http://www.openradar.me/radar?id=5035192880201728
  • Обновление : похоже, это было исправлено в iOS 11.1

Для справки, это исходная проблема Кордовы, которую я открыл, которая фиксирует это: https://issues.apache.org/jira/browse/CB-13273


3
Есть ли у вас проблемы при повороте экрана? Я пытался, но после поворота экрана все сломано (safe-area-inset- * не обновляет свои значения в зависимости от ориентации устройства; и после поворота портрета -> ландшафта -> портрета снова исходные значения тоже нарушены ). Может быть проблема с браузером apple / safari?
Хуан Мигель С.

1
В моем случае, когда я добавил, все viewport-fit=coverмое приложение показывает пустой белый экран и ничего больше. Я использую iOS11, Xcode9 на iPhone 7 Plus. Кто-нибудь испытывает подобное поведение?
Дмитрий

1
@DaveAlden - похоже, что в бета-версии 11.2 + они отказались constantот envключевого слова - см. Также: webkit.org/blog/7929/designing-websites-for-iphone-x
Брент

1
где вы помещаете основной код CSS в свое приложение? Как в каком файле? У меня ничего не работает, я использую Ionic 3.
Dimitri

2
Есть ли какие-нибудь обновления относительно проблемы вращения? Я использую iOS 12, и у меня такая же проблема. Мне кажется странным, что эта проблема сохраняется. / cc @jms
а - м

36

Для ручного исправления существующего проекта Cordova

Черные полосы

Добавьте это в свой файл info.plist . Исправление изображения запуска - это отдельный вопрос, например, как добавить изображение запуска iPhoneX

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

Белые полосы

Установите viewport-fit = cover в метатеге

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

Спасибо! Изменение .plist имеет тот же эффект, что и изменения в выбранном ответе, но НАМНОГО быстрее.
2Fwebd

Как каждая из этих задач влияет на высоту и ширину CSS-пикселей? В моем приложении есть серия узких div вверху (меню и т. Д.) ... а затем я вычисляю оставшуюся высоту пикселя, чтобы последний DIV заполнил остальную часть экрана. Прямо сейчас я вижу, что нижняя белая полоса покрывает часть этого DIV, но я также могу сказать не все из них - подразумевая, что DIV все еще не идет в нижнюю часть экрана. И, в свою очередь, мое приложение запускается под верхней белой полосой, поэтому оно даже не пытается использовать верхнее пространство.
rolinger

Я использовал, UILaunchStoryboardNameи ему удалось удалить черные полосы. Но мой экран-заставка расширяется. По какой причине? Принятый ответ не работает для меня
Хуйтинг

@coder Спасибо, но добавление UILaunchStoryboardName в список не дает мне возможности отправить в магазин приложений: ERROR ITMS-90705: «Запуск раскадровки не найден. Убедитесь, что вы указали имя файла раскадровки запуска без расширения имени файла для ключа UILaunchStoryboardName в Info.plist ".
Мэтт Робертс

@Huiting Вы нашли какое-нибудь решение по вашему делу?
LMaker

16

Вам нужно сделать 3 шага

для строки состояния iOs 11 и проблем с заголовком iPhone X


1. Крышка смотрового окна.

Добавить viewport-fit=coverв мета вашего окна просмотра в<header>

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

Демо: https://jsfiddle.net/gq5pt509 (index.html)


  1. Добавьте больше изображений-заставок в свой config.xmlинтерьер<platform name="ios">

Dont пропустите этот шаг , это требуется для получения экрана подходит для 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 -->

Демо: https://jsfiddle.net/mmy885q4 (config.xml)


  1. Исправьте свой стиль в CSS

Используйте safe-area-inset-left, safe-area-inset-right, safe-area-inset-topилиsafe-area-inset-bottom

Пример: (Используйте в своем случае!)

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

Бонус: вы можете добавить класс тела как is-androidили is-iosна устройстве.

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

Итак, вы можете сделать что-то подобное в CSS

.is-ios #header {
 // Properties
}

5

В моем случае, когда каждый экран-заставка был индивидуально разработан, а не автоматически сгенерирован или выложен в формате раскадровки, мне пришлось придерживаться своей конфигурации старого экрана запуска и добавить портретные и альбомные изображения для ориентации iPhoneX 1125 × 2436 в config.xml вот так:

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

После добавления их в config.xml («viewport-fit = cover» уже был установлен в index.hml) мое приложение, созданное с помощью Ionic Pro, заполняет весь экран на устройствах iPhoneX.


сэр, но в моем config.xml я уже добавил над этой строкой и viewport-fit = cover
Kapil soni

@Kapilsoni, тогда это может быть проблема с плагином Cordova UIWebView, WKWebView, SplashScreen или комбинацией этих конфигураций. Кроме того, вы ориентируетесь на XCode 10 или 11 в своих сборках?
TaeKwonJoe

сэр, я нацелен на XCode 10?
Kapil soni


2

Исправлена ​​проблема с поворотом экрана iPhone X / XS

На iPhone X / XS поворот экрана приведет к тому, что высота строки заголовка будет использовать неверное значение, потому что расчет safe-area-inset- * не отражал новые значения во время обновления пользовательского интерфейса. Эта ошибка существует в UIWebView даже в последней версии iOS 12. Обходной путь заключается в вставке верхнего поля в 1 пиксель и его быстром изменении в обратном направлении, что немедленно вызывает пересчет safe-area-inset- *. Несколько уродливое исправление, но оно работает, если вам по той или иной причине приходится использовать UIWebView.

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

Цель кода - вызвать небольшое изменение document.body.style.marginTop, а затем отменить его. Это не обязательно должно быть «1px». Вы можете выбрать значение, которое не заставит ваш пользовательский интерфейс мерцать, но достигнет своей цели.


UIWebView был исключен в iOS8 ... Я сомневаюсь, что какие-либо из существующих ошибок будут исправлены. Apple предупреждает при загрузке приложений, что это будет скоро прекращено ... так что пора взять на себя боль и перейти на WKWebView ...
Mozfet

2

Я разрабатываю приложения Cordova в течение 2 лет, и я потратил недели на решение связанных проблем (например, прокрутка веб-страниц при открытии клавиатуры). Вот проверенное и проверенное решение для iOS и Android.

PS: я использую iScroll для прокрутки контента

  1. Никогда не используйте viewport-fit = cover в метатеге index.html, оставьте приложение вне строки состояния. iOS будет обрабатывать правильную область для всех вариантов iPhone.
  2. В XCode снимите флажок в строке состояния шкура и требует полного экрана и не забудьте выбрать Launch Screen файл как CDVLaunchScreen
  3. В config.xml установите полноэкранный режим как false
  4. Наконец, (спасибо Эдди Вербруггену за отличные плагины) добавьте его плагин cordova-plugin-webviewcolor, чтобы установить цвет фона строки состояния и нижней области. Этот плагин позволит вам установить любой цвет, который вы хотите.
  5. Добавьте ниже в config.xml (первый ff после x - непрозрачность)

    <preference name="BackgroundColor" value="0xff088c90" />
  6. Управляйте своей позицией прокрутки самостоятельно, добавляя события фокуса к элементам ввода

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

Для Android сделайте то же самое, но вместо cordova-plugin-webviewcolor установите cordova-plugin-statusbar и cordova-plugin-navigationbar-color.

Вот код javascript, использующий эти плагины для работы как на ios, так и на 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

Если вы установите более новые версии ionicглобально, вы можете запустить, ionic cordova resourcesи он сгенерирует для вас все изображения заставки с правильными размерами.


-1

Обратите внимание, что эта статья: https://medium.com/the-web-tub/supporting-iphone-x-for-mobile-web-cordova-app-using-onsen-ui-f17a4c272fcd имеет другие размеры, чем указано выше и cordova страница плагина:

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)

Я изменил размер изображений, как указано выше, и обновил iosплатформу cordova-plugin-splashscreenдо последней версии, а после исправления второй проблемы я стал белым экраном. Однако исходное изображение-спэш теперь имеет белую рамку внизу.


1
Я могу подтвердить iPhone X при запуске симулятора Default@3x~iphone~comany.png - 1242x2436изображением
msmfsd,

Следует отметить, что правильные размеры для iPhone X следующие ... Портрет: 1125 пикселей × 2436 пикселей ... Пейзаж: 2436 пикселей × 1125 пикселей
Стерлинг Борн,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.