記一次 Weex 的 iPhone X 適配

zwwill木羽發表於2017-12-08

前言

iPhone X 上市也一月有餘了,「齊劉海」的設計給全世界的 IOS 和 M 站開發人員出了一道相容題目,預設效果問題雖不嚴重,但是足以逼瘋強迫症患者。幸得專案「空窗期」,實踐下 iPhone X 的適配。還記得之前的一篇文章嗎?《【Weex】網易嚴選 App 感受 Weex 開發》,此處將以此 demo 為基礎做展開 Weex 適配。Native 和 H5 的適配此處就不再做贅述了。「專業 IOS 開發同學就當個笑話看看吧,反正你都會,此文是寫給不會原生的朋友的」

預設的樣子

如果不仔細看,還以為是 iPhone 7 的效果,這也是官方「故意為之」的。

記一次 Weex 的 iPhone X 適配

如果你用慣了 iPhone X,無意識地開啟了一個類似上圖的 app,著實會有點難以接受。

全屏操作

開啟 iPhone X 的全屏模式其實很簡單,只需要在 Xcode 裡配置 iPhone X 的 LaunchImage 即可,也可以直接改配置檔案。

記一次 Weex 的 iPhone X 適配

可能 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 匹配,然後重新構建,你就會發現,他全屏啦!

記一次 Weex 的 iPhone X 適配

同 native 適配有何不同

Weex 針對 iPhone X 的相容直接發生在前端開發層面。

「不會搞 Native 是前提」,有了這個前提,我們就只能自己動手了。

動手的原則就是,「合理利用每寸空間,將內容展示在安全區內」。

什麼是安全區

安全區是蘋果用來描述 iPhone X 的合理顯示區域。

手機縱向持握狀態下,安全區是從螢幕最頂端往下 44 pt 開始計算的,要注意的是,它並不是和「齊劉海」完全齊平的,而是要再往下一點。「下巴」位置上,從下往上推 34 pt 以上的部分開始才被視為安全區。

記一次 Weex 的 iPhone X 適配

至於橫向就不好描述了,直接上圖吧。

記一次 Weex 的 iPhone X 適配

更多關於 iPhone X UI 適配的概念可以看看這篇文章

方向

原則上,我們是將內容顯示在安全區內,但一定是在「自然過度」的前提下。

此 demo 沒有橫屏模式,所有,唯一需要適配的就是,豎屏模式下安全區外的介面遮擋處理。

也就是上下兩個部分內收處理。空出來的部分用同色色塊填充。

記一次 Weex 的 iPhone X 適配

識別 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 的 iPhone X 適配

從最終效果圖上看,還可以,至少滿足了我的需求。只不過實現起來有些麻煩,Weex 是單頁的結構,每個頁面都需要單獨做適配,如果從 Native 上做處理,就需要有一定的 Native 開發技能,加之良好的架構和協議設計。但是,Native 的處理遠沒有 UI 處理來的靈活。

總的來講,Native 層和 UI 層的方法各有利弊,具體實施還需結合專案。

「沒有最好的錘子,只有最適合釘子的錘子?」

轉載請標明出處

作者: 木羽 zwwill

首發地址:github.com/zwwill/blog…

相關文章