ios Cordova 应用程序无法在 iPhone X(模拟器)上正确显示
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46232812/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cordova app not displaying correctly on iPhone X (Simulator)
提问by DaveAlden
I tested my Cordova-based app yesterday on the iPhone X Simulator in Xcode 9.0 (9A235) and it didn't look good. Firstly, instead of filling the full screen area, there was a black area above and below the app content. And worse, between the app content and the black was two white bars.
我昨天在 Xcode 9.0 (9A235) 中的 iPhone X Simulator 上测试了我的基于 Cordova 的应用程序,但它看起来并不好。首先,应用内容的上方和下方没有填充全屏区域,而是有一个黑色区域。更糟糕的是,在应用程序内容和黑色之间有两条白条。
Adding cordova-plugin-wkwebview-engine
so Cordova renders using WKWebView (not UIWebView) fixes the white bars.
By my app is not migrated from UIWebView to WKWebView due to performance and memory leak issues when using cordova-plugin-wkwebview-engine
which occur when loading images downloaded from Inapp Purchase hosted content into an HTML5 canvas (direct file://
access by the Webview is not possible due to security restrictions in WKWebView so the image data must be loaded via cordova-plugin-file
).
cordova-plugin-wkwebview-engine
使用 WKWebView(而不是 UIWebView)添加Cordova 渲染修复了白条。由于性能和内存泄漏问题,我的应用程序没有从 UIWebView 迁移到 WKWebView cordova-plugin-wkwebview-engine
,当加载从 Inapp Purchase 托管内容下载的图像到 HTML5 画布时会发生这种情况(file://
由于 WKWebView 中的安全限制,Webview 无法直接访问,因此图像数据必须通过cordova-plugin-file
)加载。
These screenshots show a test app with a blue background set on the <body
>.
Above and below UIWebView, you can see the white bars, but not with WKWebView:
这些屏幕截图显示了一个在<body
>上设置为蓝色背景的测试应用程序。在 UIWebView 的上方和下方,您可以看到白条,但 WKWebView 看不到:
(source: pbrd.co)
(来源:pbrd.co)
(source: pbrd.co)
(来源:pbrd.co)
Both Cordova Webviews exhibit the black areas when compared to a native app which fills the full screen area:
与填充全屏区域的本机应用程序相比,两个 Cordova Webviews 都显示黑色区域:
回答by DaveAlden
I found the solution to the white bars here:
我在这里找到了解决白条的方法:
Set viewport-fit=cover
on the viewport <meta>
tag, i.e.:
viewport-fit=cover
在视口<meta>
标签上设置,即:
<meta name="viewport" content="initial-scale=1, width=device-width, height=device-height, viewport-fit=cover">
The white bars in UIWebView then disappear:
UIWebView 中的白条然后消失:
The solution to remove the black areas (provided by @dpoguein a comment below) is to use LaunchStoryboard imageswith cordova-plugin-splashscreen
to replace the legacy launch images, used by Cordova by default. To do so, add the following to the iOS platform in config.xml
:
去除黑色区域解决方案(提供@dpogue在下面留言)是使用LaunchStoryboard图像与cordova-plugin-splashscreen
以取代传统的发射图像,使用科尔多瓦默认。为此,请将以下内容添加到 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>
Then create the images with the following dimensions in res/screen/ios
(remove any existing ones):
然后创建具有以下尺寸的图像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
Once the black bars are removed, there's another thing that's different about the iPhone X to address: The status bar is larger than 20px due to the "notch", which means any content at the far top of your Cordova app will be obscured by it:
移除黑条后,iPhone X 还需要解决另一件事:由于“缺口”,状态栏大于 20 像素,这意味着 Cordova 应用程序最顶部的任何内容都将被它遮挡:
Rather than hard-coding a padding in pixels, you can handle this automatically in CSS using the new safe-area-inset-*
constants in iOS 11.
您可以使用safe-area-inset-*
iOS 11 中的新常量在CSS 中自动处理此问题,而不是以像素为单位硬编码填充。
Note:in iOS 11.0 the function to handle these constants was called constant()
but in iOS 11.2 Apple renamed it to env()
(see here),
therefore to cover both cases you need to overload the CSS rule with both and rely on the CSS fallback mechanismto apply the appropriate one:
注意:在 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);
}
The result is then as desired: the app content covers the full screen, but is not obscured by the "notch":
结果就如你所愿:应用程序内容覆盖全屏,但没有被“缺口”遮挡:
I've created a Cordova test project which illustrates the above steps: webview-test.zip
我创建了一个 Cordova 测试项目,它说明了上述步骤:webview-test.zip
Notes:
笔记:
Footer buttons
页脚按钮
- If your app has footer buttons (as mine does), you will also need to apply
safe-area-inset-bottom
to avoid them being overlapped by the virtual Home button on iPhone X. - In my case, I couldn't apply this to
<body>
as the footer is absolutely positioned, so I needed to apply it directly to the footer:
- 如果您的应用程序有页脚按钮(就像我的一样),您还需要申请
safe-area-inset-bottom
以避免它们与 iPhone X 上的虚拟主页按钮重叠。 - 就我而言,
<body>
由于页脚是绝对定位的,因此我无法将其应用于,因此我需要将其直接应用于页脚:
.toolbar-footer{
margin-bottom: constant(safe-area-inset-bottom);
margin-bottom: env(safe-area-inset-bottom);
}
cordova-plugin-statusbar
科尔多瓦插件状态栏
- The status bar size has changed on iPhone X, so older versions of
cordova-plugin-statusbar
display incorrectly on iPhone X - Mike Hartingtonhas created this pull requestwhich applies the necessary changes.
- This was merged into the
[email protected]
release, so make sure you're using at least this version to apply to safe-area-insets
- iPhone X 上的状态栏大小已更改,因此旧版本的
cordova-plugin-statusbar
iPhone X 上显示不正确 - Mike Hartington创建了这个应用必要更改的拉取请求。
- 这已合并到
[email protected]
发行版中,因此请确保您至少使用此版本来应用于安全区域插入
splashscreen
启动画面
- The LaunchScreen storyboard constraints changed on iOS 11/iPhone X, meaning the splashscreen appeared to "jump" on launch when using existing versions of the plugin (see here).
- This was captured in bug report CB-13505, fixed PR cordova-ios#354and released in
[email protected]
, so make sure you're using a recent version of thecordova-ios
platform.
- LaunchScreen 故事板约束在 iOS 11/iPhone X 上发生了变化,这意味着在使用现有版本的插件时,启动画面似乎在启动时“跳跃”(请参阅此处)。
- 这在错误报告CB-13505 中捕获,修复了 PR cordova-ios#354并在 中发布
[email protected]
,因此请确保您使用的是该cordova-ios
平台的最新版本。
device orientation
设备方向
- When using UIWebView on iOS 11.0, rotating from portrait > landscape > portrait causes the
safe-area-inset
not to be re-applied, causing the content to be obscured by the notch again (as highlighted by jmsin a comment below). - Also happens if app is launched in landscape then rotated to portrait
- This doesn't happen when using WKWebView via
cordova-plugin-wkwebview-engine
. - Radar report: http://www.openradar.me/radar?id=5035192880201728
- Update: this appears to have been fixed in iOS 11.1
- 在 iOS 11.0 上使用 UIWebView 时,从纵向 > 横向 > 纵向旋转会导致
safe-area-inset
不会重新应用,导致内容再次被缺口遮挡(如下面的评论中由jms突出显示)。 - 如果应用程序在横向启动然后旋转到纵向,也会发生
- 通过使用 WKWebView 时不会发生这种情况
cordova-plugin-wkwebview-engine
。 - 雷达报告:http: //www.openradar.me/radar?id=5035192880201728
- 更新:这似乎已在 iOS 11.1 中修复
For reference, this is the original Cordova issue I opened which captures this: https://issues.apache.org/jira/browse/CB-13273
作为参考,这是我打开的原始 Cordova 问题,它捕获了这个:https: //issues.apache.org/jira/browse/CB-13273
回答by coder
For a manual fix to an existing cordova project
手动修复现有的cordova项目
The black bars
黑条
Add this to your info.plistfile. Fixing the launch image is a separate issue i.e. How to Add iPhoneX Launch Image
将此添加到您的info.plist文件中。修复启动图像是一个单独的问题,即如何添加 iPhoneX 启动图像
<key>UILaunchStoryboardName</key>
<string>CDVLaunchScreen</string>
The white bars
白条
Set viewport-fit=cover in the meta tag
在元标记中设置 viewport-fit=cover
<meta name="viewport" content="initial-scale=1, width=device-width, height=device-height, viewport-fit=cover">
回答by l2aelba
There is 3 steps you have to do
有3个步骤你必须做
for iOs 11 status bar & iPhone X header problems
用于 iOS 11 状态栏和 iPhone X 标题问题
1. Viewport fit cover
1.视口贴合覆盖
Add viewport-fit=cover
to your viewport's meta in <header>
添加viewport-fit=cover
到您的视口的元<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)
演示:https : //jsfiddle.net/gq5pt509(index.html)
- Add more splash imagesto your
config.xml
inside<platform name="ios">
- 向您的
config.xml
内部添加更多启动图像<platform name="ios">
Dont skip this step, this required for getting screen fitfor iPhone Xwork
不要跳过这一步,这需要让屏幕适合用于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 -->
Demo:https://jsfiddle.net/mmy885q4(config.xml)
演示:https : //jsfiddle.net/mmy885q4(config.xml)
- Fix your style on CSS
- 在 CSS 上修复您的样式
Use safe-area-inset-left
, safe-area-inset-right
, safe-area-inset-top
, or safe-area-inset-bottom
使用safe-area-inset-left
, safe-area-inset-right
, safe-area-inset-top
, 或safe-area-inset-bottom
Example:(Use in your case!)
示例:(在您的情况下使用!)
#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:You can add body class like is-android
or is-ios
on deviceready
奖励:您可以像deviceready一样is-android
或is-ios
在deviceready上添加 body 类
var platformId = window.cordova.platformId;
if (platformId) {
document.body.classList.add('is-' + platformId);
}
So you can do something like this on CSS
所以你可以在 CSS 上做这样的事情
.is-ios #header {
// Properties
}
回答by TaeKwonJoe
In my case where each splash screen was individually designed instead of autogenerated or laid out in a story board format, I had to stick with my Legacy Launch screen configuration and add portrait and landscape images to target iPhoneX 1125×2436 orientations to the config.xml like so:
在我的情况下,每个启动画面都是单独设计的,而不是自动生成或以故事板格式布局,我不得不坚持我的旧版启动屏幕配置,并将纵向和横向图像添加到 config.xml 中以 iPhoneX 1125×2436 方向为目标像这样:
<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" />
After adding these to config.xml ("viewport-fit=cover" was already set in index.hml) my app built with Ionic Pro fills the entire screen on iPhoneX devices.
将这些添加到 config.xml(“viewport-fit=cover”已在 index.hml 中设置)后,我使用 Ionic Pro 构建的应用程序填充了 iPhoneX 设备上的整个屏幕。
回答by YYL
Fix for iPhone X/XS screen rotation issue
修复 iPhone X/XS 屏幕旋转问题
On iPhone X/XS, a screen rotation will cause the header bar height to use an incorrect value, because the calculation of safe-area-inset-* was not reflecting the new values in time for UI refresh. This bug exists in UIWebView even in the latest iOS 12. A workaround is inserting a 1px top margin and then quickly reversing it, which will trigger safe-area-inset-* to be re-calculated immediately. A somewhat ugly fix but it works if you have to stay with UIWebView for one reason or another.
在 iPhone X/XS 上,屏幕旋转会导致标题栏高度使用错误的值,因为 safe-area-inset-* 的计算没有及时反映 UI 刷新的新值。即使在最新的 iOS 12 中,UIWebView 中也存在此错误。解决方法是插入 1px 上边距,然后快速反转它,这将触发 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);
The purpose of the code is to cause the document.body.style.marginTop to change slightly and then reverse it. It doesn't necessarily have to be "1px". You can pick a value that doesn't cause your UI to flicker but achieves its purpose.
代码的目的是让 document.body.style.marginTop 稍微改变然后反转。它不一定必须是“1px”。您可以选择一个不会导致 UI 闪烁但可以实现其目的的值。
回答by Brent
Just a note that the constant
keyword use for safe-area margins has been updated to env
for 11.2 beta+
请注意,constant
用于安全区域边距的关键字已更新env
为 11.2 beta+
https://webkit.org/blog/7929/designing-websites-for-iphone-x/
https://webkit.org/blog/7929/designing-websites-for-iphone-x/
回答by gdarcan
I'm developing cordova apps for 2 years and I spent weeks to solve related problems (eg: webview scrolls when keyboard open). Here's a tested and proven solution for both ios and android
我开发了 2 年的cordova 应用程序,我花了数周时间来解决相关问题(例如:键盘打开时 webview 滚动)。这是针对 ios 和 android 的经过测试和验证的解决方案
P.S.: I'm using iScroll for scrolling content
PS:我使用 iScroll 滚动内容
- Never use viewport-fit=coverat index.html's meta tag, leave the app stay out of statusbar. iOS will handle proper area for all iPhone variants.
- In XCode uncheck hide status barand requires full screenand don't forget to select Launch Screen File as CDVLaunchScreen
- In config.xml set fullscreenas false
- Finally, (thanks to Eddy Verbruggen for great plugins) add his plugin cordova-plugin-webviewcolorto set statusbar and bottom area background color. This plugin will allow you to set any color you want.
Add below to config.xml (first ff after x is opacity)
<preference name="BackgroundColor" value="0xff088c90" />
Handle your scroll position yourself by adding focus events to input elements
iscrollObj.scrollToElement(elm, transitionduration ... etc)
- 永远不要在 index.html 的元标记中使用viewport-fit=cover,让应用远离状态栏。iOS 将处理所有 iPhone 变体的适当区域。
- 在 XCode 中取消选中隐藏状态栏并需要全屏,不要忘记选择 Launch Screen File 作为CDVLaunchScreen
- 在 config.xml 中将fullscreen设置为false
- 最后,(感谢 Eddy Verbruggen 提供了很棒的插件)添加他的插件cordova-plugin-webviewcolor来设置状态栏和底部区域的背景颜色。这个插件可以让你设置任何你想要的颜色。
将下面添加到 config.xml (x 之后的第一个 ff 是不透明度)
<preference name="BackgroundColor" value="0xff088c90" />
通过向输入元素添加焦点事件来自己处理滚动位置
iscrollObj.scrollToElement(elm, transitionduration ... etc)
For android, do the same but instead of cordova-plugin-webviewcolor, install cordova-plugin-statusbarand cordova-plugin-navigationbar-color
对于 android,执行相同操作,但不要安装cordova-plugin- webviewcolor,安装cordova-plugin-statusbar和cordova-plugin-navigationbar-color
Here's a javascript code using those plugins to work on both ios and android:
这是使用这些插件在 ios 和 android 上工作的 javascript 代码:
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);
}
}
回答by nebulr
If you install newer versions of ionic
globally you can run
ionic cordova resources
and it will generate all of the splashscreen images for you along with the correct sizes.
如果您ionic
全局安装较新版本的,您可以运行
ionic cordova resources
,它会为您生成所有启动画面图像以及正确的大小。
回答by msmfsd
Please note that this article: https://medium.com/the-web-tub/supporting-iphone-x-for-mobile-web-cordova-app-using-onsen-ui-f17a4c272fcdhas different sizes than above and cordova plugin page:
请注意这篇文章: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)
I resized images as above and updated ios
platform and cordova-plugin-splashscreen
to latest and the flash to white screen after a second issue was fixed. However the initial spash image has a white border at bottom now.
在第二个问题得到修复后,我调整了上述图像的大小并更新了ios
平台和cordova-plugin-splashscreen
最新版本,并且闪光灯变为白屏。然而,最初的 spash 图像现在底部有一个白色边框。