126

我昨天在 Xcode 9.0 (9A235) 的 iPhone X 模拟器上测试了我的基于 Cordova 的应用程序,它看起来并不好。首先,不是填充全屏区域,而是在应用内容的上方和下方有一个黑色区域。更糟糕的是,在应用内容和黑色之间是两条白条。

添加cordova-plugin-wkwebview-engine使用 WKWebView(不是 UIWebView)的 Cordova 渲染修复了白条。由于性能和内存泄漏问题,我的应用程序未从 UIWebView 迁移到 WKWebView,因为在cordova-plugin-wkwebview-engine将从 Inapp Purchase 托管的内容下载的图像加载到 HTML5 画布时发生这种情况(file://由于 WKWebView 中的安全限制,无法通过 Webview 直接访问,所以图像数据必须通过cordova-plugin-file) 加载。

<body这些屏幕截图显示了一个在>上设置了蓝色背景的测试应用程序。在 UIWebView 的上方和下方,您可以看到白条,但使用 WKWebView 时看不到:


(来源:pbrd.co


(来源:pbrd.co

与填充全屏区域的本机应用程序相比,两个 Cordova Webviews 都显示黑色区域:

4

9 回答 9

255

我在这里找到了白条的解决方案:

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 应用程序最顶部的任何内容都将被它遮挡:

safe-area-inset-*您可以使用iOS 11 中的新常量在 CSS 中自动处理此问题,而不是硬编码以像素为单位的填充。

注意:在 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);
}

科尔多瓦插件状态栏

  • iPhone X 上的状态栏大小已更改,因此旧版本cordova-plugin-statusbar在 iPhone X 上显示不正确
  • Mike Hartington创建了这个应用必要更改的拉取请求。
  • 这已合并到cordova-plugin-statusbar@2.3.0版本中,因此请确保您至少使用此版本以应用于安全区域插入

闪屏

  • 在 iOS 11/iPhone X 上,LaunchScreen 故事板约束发生了变化,这意味着在使用现有版本的插件时,启动画面似乎会“跳跃”(参见此处)。
  • 这在错误报告CB-13505中捕获,修复了 PR cordova-ios#354并在 中发布cordova-ios@4.5.4,因此请确保您使用的是最新版本的cordova-ios平台。

设备方向

  • 在 iOS 11.0 上使用 UIWebView 时,从纵向 > 横向 > 纵向旋转会导致safe-area-inset不重新应用,导致内容再次被凹口遮挡(如下面评论中jms突出显示的那样)。
  • 如果应用程序以横向启动然后旋转为纵向也会发生
  • 使用 WKWebView via 时不会发生这种情况cordova-plugin-wkwebview-engine
  • 雷达报告:http ://www.openradar.me/radar?id=5035192880201728
  • 更新:这似乎已在 iOS 11.1 中修复

作为参考,这是我打开的原始 Cordova 问题,其中包含以下内容:https ://issues.apache.org/jira/browse/CB-13273

于 2017-09-15T06:10:02.157 回答
37

对于现有的cordova项目的手动修复

黑条

将此添加到您的info.plist文件中。修复启动图像是一个单独的问题,即如何添加 iPhoneX 启动图像

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

白条

在 meta 标签中设置 viewport-fit=cover

<meta name="viewport" content="initial-scale=1, width=device-width, height=device-height, viewport-fit=cover">
于 2017-11-15T21:19:56.267 回答
17

您必须执行 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">

不要跳过这一步,这是使屏幕适合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-iosdeviceready上添加身体类

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

所以你可以在 CSS 上做这样的事情

.is-ios #header {
 // Properties
}
于 2018-01-31T14:24:54.063 回答
5

在我的情况下,每个初始屏幕都是单独设计的,而不是自动生成的或以故事板格式布置的,我必须坚持使用我的 Legacy Launch 屏幕配置,并将纵向和横向图像添加到 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" />

将这些添加到 config.xml(“viewport-fit=cover”已在 index.hml 中设置)后,我使用 Ionic Pro 构建的应用程序会填满 iPhoneX 设备上的整个屏幕。

于 2018-05-01T19:09:20.907 回答
2

我正在开发 Cordova 应用程序 2 年,我花了数周时间解决相关问题(例如:键盘打开时 webview 滚动)。这是适用于 ios 和 android 的经过测试和验证的解决方案

PS:我正在使用 iScroll 滚动内容

  1. 切勿在 index.html 的元标记处使用viewport-fit=cover,让应用远离状态栏。iOS 将为所有 iPhone 变体处理适当的区域。
  2. 在 XCode 中取消选中隐藏状态栏要求全屏,不要忘记选择启动屏幕文件作为CDVLaunchScreen
  3. 在 config.xml 中将全屏设置为false
  4. 最后,(感谢 Eddy Verbruggen 提供的出色插件)添加他的插件cordova-plugin-webviewcolor来设置状态栏和底部区域背景颜色。这个插件将允许你设置任何你想要的颜色。
  5. 在 config.xml 中添加以下内容(x 之后的第一个 ff 是不透明度)

    <preference name="BackgroundColor" value="0xff088c90" />
    
  6. 通过将焦点事件添加到输入元素来自己处理滚动位置

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

对于 android,做同样的事情,但不是cordova-plugin-webviewcolor,安装cordova-plugin-statusbarcordova-plugin-navigationbar-color

这是使用这些插件在 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);
    }
}
于 2019-10-22T01:26:43.737 回答
2

请注意,constant用于安全区域边距的关键字已更新env为 11.2 beta+

https://webkit.org/blog/7929/designing-websites-for-iphone-x/

于 2017-11-15T22:19:01.380 回答
2

修复 iPhone X/XS 屏幕旋转问题

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

代码的目的是使 document.body.style.marginTop 发生轻微变化,然后将其反转。它不一定必须是“1px”。您可以选择一个不会导致 UI 闪烁但能达到目的的值。

于 2019-01-10T01:26:53.610 回答
1

如果您安装较新版本的ionicglobal 您可以运行 ionic cordova resources,它将为您生成所有启动画面图像以及正确的尺寸。

于 2017-12-20T00:09:43.593 回答
0

查看此链接,有时可能会有所帮助。我可以使用下面提供的解决方案来解决问题。 https://github.com/apache/cordova-plugin-wkwebview-engine/issues/108

添加

[wkWebView.scrollView setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];

在 wkWebView.UIDelegate = self.uiDelegate 之前;在 CDVWebViewEngine.m

于 2021-12-03T13:36:48.860 回答