Приложение Кордовы не отображается правильно на iPhone X (Simulator)
Вчера я тестировал свое приложение на базе Cordova на iPhone X Simulator в Xcode 9.0 (9A235), и оно не выглядело хорошо.
Во-первых, вместо заполнения полноэкранной области над и под содержимым приложения была черная область.
И что еще хуже, между контентом приложения и черным было две белые полосы.
Добавление cordova-plugin-wkwebview-engine
для рендеринга Cordova с использованием WKWebView (не UIWebView) исправляет белые полосы.
Моим приложением не переносится из UIWebView в WKWebView из-за проблем с производительностью и утечкой памяти при использовании cordova-plugin-wkwebview-engine
, возникающих при загрузке изображений, загруженных из Inapp. ограничения безопасности в WKWebView, поэтому данные изображения должны быть загружены через cordova-plugin-file
).
На этих снимках экрана показано тестовое приложение с синим фоном, установленное на <body
>.
Выше и ниже UIWebView вы можете видеть белые полосы, но не с WKWebView:
![]()
(источник: pbrd.co)
![]()
(источник: pbrd.co)
Оба веб-просмотра Cordova показывают черные области по сравнению с нативным приложением, которое заполняет всю область экрана:
![]()
Ответы
Ответ 1
Я нашел решение для белых баров здесь:
Установите viewport-fit=cover
в теге viewport <meta>
, т.е.:
<meta name="viewport" content="initial-scale=1, width=device-width, height=device-height, viewport-fit=cover">
Белые полосы в UIWebView затем исчезают:
![12887115_Simulator+Screen+Shot+-+iPhone+X+-+2017-09-14+at+15.52.54.png]()
Решение об удалении черных областей (предоставлено @dpogue в комментарии ниже) заключается в использовании Изображения LaunchStoryboard с помощью cordova-plugin-splashscreen
, чтобы заменить устаревшие изображения запуска, используемые по умолчанию Кордовой. Для этого добавьте следующее на платформу iOS в config.xml
:
<platform name="ios">
<splash src="res/screen/ios/[email protected]~iphone~anyany.png" />
<splash src="res/screen/ios/[email protected]~iphone~comany.png" />
<splash src="res/screen/ios/[email protected]~iphone~comcom.png" />
<splash src="res/screen/ios/[email protected]~iphone~anyany.png" />
<splash src="res/screen/ios/[email protected]~iphone~anycom.png" />
<splash src="res/screen/ios/[email protected]~iphone~comany.png" />
<splash src="res/screen/ios/[email protected]~ipad~anyany.png" />
<splash src="res/screen/ios/[email protected]~ipad~comany.png" />
<!-- more iOS config... -->
</platform>
Затем создайте изображения со следующими размерами в res/screen/ios
(удалите все существующие):
[email protected]~iphone~anyany.png - 1334x1334
[email protected]~iphone~comany.png - 750x1334
[email protected]~iphone~comcom.png - 1334x750
[email protected]~iphone~anyany.png - 2208x2208
[email protected]~iphone~anycom.png - 2208x1242
[email protected]~iphone~comany.png - 1242x2208
[email protected]~ipad~anyany.png - 2732x2732
[email protected]~ipad~comany.png - 1278x2732
Как только черные полосы удаляются, есть еще одна вещь, которая отличается от iPhone X: Строка состояния больше 20 пикселей из-за "выреза", что означает, что любой контент на самом верху вашего приложения в Кордове будет скрытый им:
![VNFYb.png]()
Вместо жесткого кодирования отступов в пикселях вы можете обрабатывать это автоматически в 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);
}
Результат тогда по желанию: содержимое приложения охватывает весь экран, но не закрывается "выемкой":
![Simulator%20Screen%20Shot%20-%20iPhone%20X%20-%202017-09-15%20at%2009.20.48.png]()
Я создал тестовый проект 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
- Майк Хартингтон создал этот запрос на перенос, который применяет необходимые изменения.
- Это было объединено с выпуском
[email protected]
, поэтому убедитесь, что вы используете, по крайней мере, эту версию, чтобы применить к вложениям безопасной области.
SplashScreen
- Ограничения раскадровки LaunchScreen изменены на iOS 11/iPhone X, а это означает, что заставка запускается при запуске при использовании существующих версий плагина (см. здесь).
- Это было зафиксировано в отчете об ошибке CB-13505, исправлено PR cordova -ios # 354 и выпущен в
[email protected]
, поэтому убедитесь, что вы используете последнюю версию платформы cordova-ios
.
ориентация устройства
- При использовании UIWebView на iOS 11.0 поворот из портретa > пейзаж > портрет заставляет
safe-area-inset
не применяться повторно, в результате чего содержимое снова затушевывается выемкой (как выделено jms в комментарии ниже).
- Также происходит, если приложение запускается в ландшафте, а затем поворачивается на портрет
- Этого не происходит при использовании WKWebView через
cordova-plugin-wkwebview-engine
.
- Радарный отчет: http://www.openradar.me/radar?id=5035192880201728
- Обновить: это, по-видимому, исправлено в iOS 11.1
Для справки, это оригинальная проблема Cordova, которую я открыл, которая фиксирует это: https://issues.apache.org/jira/browse/CB-13273
Ответ 2
Для ручного исправления существующего проекта cordova
Черные полосы
Добавьте это в свой файл info.plist. Исправление образа запуска - отдельная проблема, а именно Как добавить изображение запуска iPhoneX
<key>UILaunchStoryboardName</key>
<string>CDVLaunchScreen</string>
Белые полосы
Установить viewport-fit = обложка в метатеге
<meta name="viewport" content="initial-scale=1, width=device-width, height=device-height, viewport-fit=cover">
Ответ 3
Есть 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)
- Добавьте больше заставочных изображений в ваш
config.xml
внутри <platform name="ios">
Не пропустите этот шаг, это необходимо для подгонки экрана под iPhone X
<splash src="your_path/[email protected]~ipad~anyany.png" /> <!-- 2732x2732 -->
<splash src="your_path/[email protected]~ipad~comany.png" /> <!-- 1278x2732 -->
<splash src="your_path/[email protected]~iphone~anyany.png" /> <!-- 1334x1334 -->
<splash src="your_path/[email protected]~iphone~comany.png" /> <!-- 750x1334 -->
<splash src="your_path/[email protected]~iphone~comcom.png" /> <!-- 1334x750 -->
<splash src="your_path/[email protected]~iphone~anyany.png" /> <!-- 2208x2208 -->
<splash src="your_path/[email protected]~iphone~anycom.png" /> <!-- 2208x1242 -->
<splash src="your_path/[email protected]~iphone~comany.png" /> <!-- 1242x2208 -->
Демонстрация: https://jsfiddle.net/mmy885q4 (config.xml)
- Исправьте свой стиль на 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
на deviceready
var platformId = window.cordova.platformId;
if (platformId) {
document.body.classList.add('is-' + platformId);
}
Так что вы можете сделать что-то подобное на CSS
.is-ios #header {
// Properties
}
Ответ 4
В моем случае, когда каждый заставочный экран разрабатывался индивидуально, а не создавался автоматически или выкладывался в формате раскадровки, мне приходилось придерживаться конфигурации экрана Legacy Launch и добавлять портретные и альбомные изображения для целевых ориентаций 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.
Ответ 5
Просто обратите внимание, что использование ключевого слова constant
для полей безопасной зоны обновлено до env
для 11.2 beta +
https://webkit.org/blog/7929/designing-websites-for-iphone-x/
Ответ 6
Исправлена проблема с поворотом экрана 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);
Ответ 7
Если вы устанавливаете более новые версии ionic
по всему миру, вы можете запускать
ionic cordova resources
, и он сгенерирует все изображения заставки для вас вместе с правильными размерами.
Ответ 8
Я разрабатываю приложения Cordova в течение 2 лет, и я потратил недели на решение связанных проблем (например, прокрутки веб-просмотра при открытой клавиатуре). Здесь проверенное и проверенное решение для iOS и Android
П.С.: Я использую iScroll для прокрутки контента
- Никогда не используйте viewport-fit = cover в метатеге index.html, оставляйте приложение вне строки состояния. iOS будет обрабатывать правильную область для всех вариантов iPhone.
- В XCode снимите флажок скрыть строку состояния, а для требуется полноэкранный режим, и не забудьте выбрать файл запуска экрана как CDVLaunchScreen
- В config.xml установите полноэкранный режим как false
- .Наконец, (спасибо Эдди Вербруггену за отличные плагины) добавьте его плагин cordova-plugin-webviewcolor, чтобы установить статусбар и цвет фона нижней области. Этот плагин позволит вам установить любой цвет, который вы хотите.
Добавьте ниже в config.xml (первый ff после x - непрозрачность)
<preference name="BackgroundColor" value="0xff088c90" />
Обрабатывайте положение прокрутки самостоятельно, добавляя события фокуса к элементам ввода
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);
}
}
Ответ 9
Обратите внимание, что эта статья: https://medium.com/the-web-tub/supporting-iphone-x-for-mobile-web-cordova-app-using-onsen-ui-f17a4c272fcd имеет разные размеры, чем указано выше, и страницу плагина cordova:
[email protected]~iphone~anyany.png (= 1334x1334 = [email protected])
[email protected]~iphone~comany.png (= 750x1334 = [email protected])
[email protected]~iphone~comcom.png (= 750x750 = [email protected])
[email protected]~iphone~anyany.png (= 2436x2436 = [email protected])
[email protected]~iphone~anycom.png (= 2436x1242 = [email protected])
[email protected]~iphone~comany.png (= 1242x2436 = [email protected])
[email protected]~ipad~anyany.png (= 2732x2732 = [email protected])
[email protected]~ipad~comany.png (= 1278x2732 = [email protected])
Я изменил размеры изображений, как указано выше, и обновил платформу ios
и cordova-plugin-splashscreen
до последней версии, а экран с подсветкой на белый после устранения второй проблемы. Однако исходное эскизное изображение теперь имеет белую границу внизу.