Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【适配】记一次 Weex 的 iPhone X 适配 #15

Open
zwwill opened this issue Dec 7, 2017 · 0 comments
Open

【适配】记一次 Weex 的 iPhone X 适配 #15

zwwill opened this issue Dec 7, 2017 · 0 comments

Comments

@zwwill
Copy link
Owner

zwwill commented Dec 7, 2017

前言

iPhone X 上市也一月有余了,「齐刘海」的设计给全世界的 IOS 和 M 站开发人员出了一道兼容题目,默认效果问题虽不严重,但是足以逼疯强迫症患者。幸得项目「空窗期」,实践下 iPhone X 的适配。还记得之前的一篇文章吗?《【Weex】网易严选 App 感受 Weex 开发》,此处将以此 demo 为基础做展开 Weex 适配。Native 和 H5 的适配此处就不再做赘述了。「专业 IOS 开发同学就当个笑话看看吧,反正你都会,此文是写给不会原生的朋友的」

默认的样子

如果不仔细看,还以为是 iPhone 7 的效果,这也是官方「故意为之」的。

如果你用惯了 iPhone X,无意识地打开了一个类似上图的 app,着实会有点难以接受。

全屏操作

打开 iPhone X 的全屏模式其实很简单,只需要在 Xcode 里配置 iPhone X 的 LaunchImage 即可,也可以直接改配置文件。

可能 Weex Toolkit 构建出来的 Platform 内不含这两个配置图片,不过没关系,右击选择「Show in Finder」,更改 「Contents.json」 配置文件。

{
    "images" : [
        {
            "extent" : "full-screen",
            "idiom" : "iphone",
            "subtype" : "2436h",
            "filename" : "Default2@3x-1.png",
            "minimum-system-version" : "11.0",
            "orientation" : "portrait",
            "scale" : "3x"
        },
        {
            "extent" : "full-screen",
            "idiom" : "iphone",
            "subtype" : "2436h",
            "filename" : "Default2@3x.png",
            "minimum-system-version" : "11.0",
            "orientation" : "landscape",
            "scale" : "3x"
        },
        {
            // other conf
        }
    ],
    "info" : {
        "version" : 1,
        "author" : "xcode"
    }
}

再添加两张 1125×2436 的图片,记得名字需要和 filename 匹配,然后重新构建,你就会发现,他全屏啦!

同 native 适配有何不同

Weex 针对 iPhone X 的兼容直接发生在前端开发层面。

「不会搞 Native 是前提」,有了这个前提,我们就只能自己动手了。

动手的原则就是,「合理利用每寸空间,将内容展示在安全区内」。

什么是安全区

安全区是苹果用来描述 iPhone X 的合理显示区域。

手机纵向持握状态下,安全区是从屏幕最顶端往下 44 pt 开始计算的,要注意的是,它并不是和「齐刘海」完全齐平的,而是要再往下一点。「下巴」位置上,从下往上推 34 pt 以上的部分开始才被视为安全区。

至于横向就不好描述了,直接上图吧。

更多关于 iPhone X UI 适配的概念可以看看这篇文章

方向

原则上,我们是将内容显示在安全区内,但一定是在「自然过度」的前提下。

此 demo 没有横屏模式,所有,唯一需要适配的就是,竖屏模式下安全区外的界面遮挡处理。

也就是上下两个部分内收处理。空出来的部分用同色色块填充。

识别 iPhone X

既要适配 iPhone X 又不能影响其他系统,那就需要做「特殊识别处理」。

怎么识别 iPhone X?

幸运的是,Weex 官方有 API 提供平台消息,weex.config

weex.config

该变量包含了当前 Weex 页面的所有环境信息,包括不仅限于:

bundleUrl: JS bundle 的 URL,和页面的 URL 一致。

env: Object: 环境对象。

  • weexVersion: string: Weex sdk 版本。
  • appName: string: 应用名字。
  • appVersion: string: 应用版本。
  • platform: string: 平台信息,是 iOS、Android 还是 Web。
  • osName: string: iOS或者android,表示操作系统的名称.
  • osVersion: string: 系统版本。
  • deviceModel: string: 设备型号 (仅原生应用)
  • deviceWidth: number: 设备宽度。Weex 默认以宽度为 750px 做适配渲染,要获得750px下的屏幕高度,可以通过height = 750/deviceWidth*deviceHeight 公式获得,可以使用到 CSS 中,用来设置全屏尺寸
  • deviceHeight: number: 设备高度。

iPhone X 环境下,weex.config.env.deviceModel 将返回 iPhone X 的特有标识 'iPhone10,3 or iPhone10,6',「注意 Xcode 虚拟机拿到的未必是正确的标识」

iPhone 5 - X 的标示

iPhone models
5 iPhone5,1 和 iPhone5,2
5c iPhone5,3 和 iPhone5,4
5s iPhone6,1 和 iPhone6,2
6 iPhone7,2
6 Plus iPhone7,1
6s iPhone8,1
6s Plus iPhone8,2
SE iPhone8,4
7 iPhone9,1 和 iPhone9,3
7 Plus iPhone9,2 和 iPhone9,4
8 iPhone10,1 和 iPhone10,4
8 Plus iPhone10,2 和 iPhone10,5
X iPhone10,3 和 iPhone10,6

更多关于 iPhone 的信息可参考这里

或者根据 操作系统 & 像素比 & 屏幕尺寸 组合判断是否是「刘海屏」。

留白

在识别到 iPhone X 的标识后,做相应的留白即可,就这么简单,复杂度由你的项目决定,一般情况下,Weex 构建的项目还是很好适配的。

计算属性和 class 绑定

最基本的做法就是使用计算属性得到是否为 iPhone X 标记,在配合 class 绑定的「数组语法」可以轻松实现适配。

<template>
    <div :class="['wrapper', isipx?'w-ipx':'']">
    </div>
</template>
<script>
    export default {
        data () {},
        computed:{
            isipx:function () {
                return weex && (weex.config.env.deviceModel === 'iPhone10,3' || weex.config.env.deviceModel === 'iPhone10,6');
            }
        },
    }
</script>
<style scoped>
    .wrapper{
        /* 正常样式 */
    }
    .w-ipx{
        /* iPhone X 样式 */
    }

</style>

此处需要注意,在初始化时计算属性的作用域内未必每次都能拿到 weex 实例,所以必须做好容错。

mixin 配合 router

如果是使用了 vue-router 可以使用 mixin 函数混入,非常方便。

<template>
    <div :class="['wrapper', isIpxFuc()?'w-ipx':'']">
    </div>
</template>
<script>
    export default {
        data () {}
    }
</script>
<style scoped>
    .wrapper{
        /* 正常样式 */
    }
    .w-ipx{
        /* iPhone X 样式 */
    }
</style>

总结

从最终效果图上看,还可以,至少满足了我的需求。只不过实现起来有些麻烦,Weex 是单页的结构,每个页面都需要单独做适配,如果从 Native 上做处理,就需要有一定的 Native 开发技能,加之良好的架构和协议设计。但是,Native 的处理远没有 UI 处理来的灵活。

总的来讲,Native 层和 UI 层的方法各有利弊,具体实施还需结合项目。

「没有最好的锤子,只有最适合钉子的锤子🔨」

转载请标明出处
作者: 木羽 zwwill
首发地址:#15

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant