微信小程序適配iPhone X總結(jié)
本文主要介紹我們的知識(shí)小集小程序在適配 iPhone X 屏幕時(shí)遇到的一些問題以及總結(jié),希望對(duì)你的小程序開發(fā)能有所幫助。
iPhone X 屏幕數(shù)據(jù)
在去年 9 月份 iPhone X 正式發(fā)布后,引發(fā)了一波 iOS App 適配 iPhone X 的熱潮和技術(shù)文章。我們這里先簡(jiǎn)單總結(jié)一下 iPhone X 屏幕的基礎(chǔ)數(shù)據(jù),方便后續(xù)在小程序開發(fā)中進(jìn)行適配。
- 屏幕尺寸:5.8 英寸(對(duì)角線)
- 屏幕物理分辨率:1125px × 2436px,458 ppi
- 實(shí)際開發(fā)適配尺寸:375pt × 812pt,@3x
此外,由于在 iPhone X 屏幕頂部狀態(tài)欄區(qū)域有“齊劉海”,以及在屏幕底部增加了“操作條”,如下圖所示,因此,我們?cè)陂_發(fā)中需要注意安全區(qū)域的問題。
根據(jù)蘋果官方的文檔,iPhone X 頂部狀態(tài)欄的適配安全區(qū)域的高度為 44pt,底部操作條區(qū)域的高度為 34pt。另外,在 iPhone X 中,一些系統(tǒng) Bar 的默認(rèn)高度相比于之前的設(shè)備也發(fā)生了變化,如下表所示。

所以在 iOS App 開發(fā)中,如果我們使用系統(tǒng)默認(rèn)的 UINavigationController 和 UITabBarController 時(shí),則無(wú)需額外的適配工作,iOS 系統(tǒng)會(huì)自動(dòng)適配好相關(guān) Bar 的安全區(qū)域問題。如果我們使用了自定義的導(dǎo)航欄和標(biāo)簽欄,則需要注意根據(jù)設(shè)備類型區(qū)分設(shè)置這些 Bar 的不同高度。
小程序的尺寸單位
為了解決不同屏幕尺寸的適配問題,小程序自己定了一個(gè)尺寸單位:rpx(responsive pixel),它可以根據(jù)屏幕寬度進(jìn)行自適應(yīng)。小程序中規(guī)定,所有設(shè)備的屏幕寬度都為 750rpx,根據(jù)設(shè)備屏幕實(shí)際寬度的不同,1rpx 所代表的實(shí)際像素值也不一樣。
根據(jù)微信開發(fā)文檔,在 4.7 英寸的 iPhone 設(shè)備上(iPhone 6/7/8),屏幕寬度為 375px(此處應(yīng)該理解為 375 point),共有 750 個(gè)物理像素,則 750rpx = 375px = 750 物理像素,1rpx = 0.5px = 1物理像素。
小程序中如何判斷設(shè)備為 iPhone X
上面我們簡(jiǎn)要介紹了 iPhone X 的屏幕數(shù)據(jù)和小程序中的尺寸單位作為鋪墊,現(xiàn)在終于要切入正題了,要在小程序中適配 iPhone X 屏幕,首先我們需要知道如何判斷設(shè)備類型。
微信的小程序 API 中提供了一個(gè) wx.getSystemInfo(OBJECT) 方法用于獲取用戶手機(jī)的系統(tǒng)信息和設(shè)備信息,包含如下數(shù)據(jù):

上述每個(gè)字段的含義詳見文檔,我們不再一一贅述。
因此,我們可以根據(jù)該方法返回的手機(jī)型號(hào)字段 model 是否包含 iPhone X 字符串來(lái)判斷設(shè)備是否為 iPhone X,也可以根據(jù) screenHeight 的高度是否等于 812 來(lái)判斷。
NOTE: 這里有一個(gè)小坑需要注意,在微信開發(fā)者工具中的模擬器,如果選擇為 iPhone X,此時(shí)獲取到的 model 值為 iPhone X,導(dǎo)致我以為真機(jī)也是這個(gè)值,于是直接用 if (model == 'iPhone X') 來(lái)判斷,但其實(shí)真機(jī)下 model 的值為這種格式: iPhone X (GSM+CDMA),因此我們需要用字符串檢索匹配進(jìn)行判斷。
綜上,我們可以在 app.js 的 globalData 中添加一個(gè)字段 isIPX 用于標(biāo)識(shí)當(dāng)前設(shè)備是否為 iPhone X,然后在小程序啟動(dòng)時(shí) onLaunch 中調(diào)用 wx.getSystemInfo(OBJECT) 方法并在其 success 回調(diào)中讀取 model 字段進(jìn)行分析,代碼大致如下:
- App({
- // 全局?jǐn)?shù)據(jù)
- globalData: {
- // 其他數(shù)據(jù)定義 ...
- isIPX: false, // 當(dāng)前設(shè)備是否為 iPhone X
- },
- // 小程序啟動(dòng)入口
- onLaunch: function (options) {
- // 其他啟動(dòng)代碼...
- // 判斷設(shè)備是否為 iPhone X
- this.checkIsIPhoneX()
- },
- checkIsIPhoneX: function() {
- const self = this
- wx.getSystemInfo({
- success: function (res) {
- // 根據(jù) model 進(jìn)行判斷
- if (res.model.search('iPhone X') != -1) {
- self.globalData.isIPX = true
- }
- // 或者根據(jù) screenHeight 進(jìn)行判斷
- // if (res.screenHeight == 812) {
- // self.globalData.isIPX = true
- // }
- }
- })
- },
- }
如果需要小程序啟動(dòng)時(shí)立即獲取設(shè)備相關(guān)信息,也可以調(diào) wx.getSystemInfoSync() 方法,它會(huì)同步獲取數(shù)據(jù)并立即返回。
頁(yè)面適配實(shí)戰(zhàn)
在小程序頁(yè)面開發(fā)中,涉及到需要適配 iPhone X 的地方主要有:導(dǎo)航欄(NavigationBar),標(biāo)簽欄(TabBar)以及頁(yè)面底部的吸底按鈕。
導(dǎo)航欄和標(biāo)簽欄適配
如果我們使用微信小程序官方組件進(jìn)行開發(fā),沒有進(jìn)行自定義,在 app.json 文件中設(shè)置 tabBar 頁(yè)面,且 window 的 navigationStyle 值為 default,那么我們無(wú)需在 iPhone X 中對(duì)導(dǎo)航欄和標(biāo)簽欄進(jìn)行適配,微信會(huì)自動(dòng)幫我們適配好,如下圖為知識(shí)小集小程序的首頁(yè):

但是我們?nèi)绻亲远x導(dǎo)航欄(在 app.json 文件中設(shè)置 window 的 navigationStyle 為 custom,此時(shí)只保留右上角膠囊狀的按鈕,需要開發(fā)者自己畫導(dǎo)航欄樣式)和標(biāo)簽欄,則我們需要在每個(gè)頁(yè)面中判斷設(shè)備類型,并針對(duì) iPhone X 屏幕在安全區(qū)域內(nèi)進(jìn)行布局,并修改相關(guān) Bar 的高度值(見上述表格)。
以自定義導(dǎo)航欄適配為例,步驟如下:
(1)在每個(gè)頁(yè)面的 page.js 中先讀取 app.js 中的 isIPX 值,如下:
- const app = getApp()
- Page({
- data: {
- // 頁(yè)面其他數(shù)據(jù)...
- isIPX: app.globalData.isIPX,
- },
- // 其他代碼
- }
(2)然后在 page.wxss 樣式文件中對(duì)某一個(gè)視圖 View 分別為普通屏幕和 iPhone X 屏幕寫兩種樣式,如下:
- .navi-bar-view {
- height: 64px;
- /* 其他樣式值 */
- }
- .navi-bar-view-IPX {
- height: 88px;
- /* 其他樣式值 */
- }
(3)***在 page.wxml 頁(yè)面結(jié)構(gòu)布局中根據(jù) isIPX 的值給 View 設(shè)置不同的 class 樣式,如下:
- <view class="{{isIPX ? 'navi-bar-view-IPX' : 'navi-bar-view'}}">
- </view>
此外,對(duì)于自定義導(dǎo)航欄和標(biāo)簽欄,我建議還是要遵循 iPhone UI 的設(shè)計(jì)規(guī)范,樣式可以參考蘋果官方的渲染圖:

吸底按鈕適配
在小程序頁(yè)面中,吸底按鈕是很常見的一種設(shè)計(jì),我們一般會(huì)把一些重要的按鈕放在頁(yè)面底部懸浮不動(dòng),例如我們知識(shí)小集小程序的“小集詳情頁(yè)”底部的“收藏”和“轉(zhuǎn)發(fā)”按鈕:

在 iPhone X 中我們需要把吸底按鈕往上偏移 34 像素,可通過在 CSS 樣式中設(shè)置 padding-bottom 為 34px 實(shí)現(xiàn),參考代碼如下:
- .feed-bottom-view {
- width: 100%;
- height: 48px; /* 吸底按鈕的高度 */
- bottom: 0;
- opacity: 0.95;
- position: fixed;
- border-top-style: solid;
- border-top-width: 0.5px; /* 分割線的高度 */
- border-color: lightgrey;
- background-color: #F8F8F8;
- }
- .feed-bottom-view-IPX {
- /* iPhone X 內(nèi)容往上偏移 34px */
- padding-bottom: 34px;
- }
- <view class="{{isIPX ? 'feed-bottom-view feed-bottom-view-IPX' : 'feed-bottom-view'}}">
- <!-- 底部吸底按區(qū)域 -->
- </view>
備注:如前面所述,對(duì)于不同設(shè)備寬度,1rpx 所代表的實(shí)際像素值也不一樣,而在不同尺寸的 iPhone 設(shè)備(3.5/4.0/4.7/5.5 英寸)中,雖然它們的寬度不同,但其導(dǎo)航欄+狀態(tài)欄的高度都為 64pt(iPhone X 為 88pt),標(biāo)簽欄 TabBar 的高度都為 49pt(iPhone X 為 83pt)。所以在小程序開發(fā)中,當(dāng)我們需要自定義導(dǎo)航欄、標(biāo)簽欄,或者適配 iPhone X 頂部和底部安全區(qū)域時(shí),我建議此處的單位直接使用 px(在小程序中對(duì)應(yīng) iOS 開發(fā)中的點(diǎn) pt)而不使用 rpx(當(dāng)然頁(yè)面的其他元素的尺寸描述還是推薦使用 rpx),以確保最終渲染顯示的高度與 iOS 系統(tǒng)默認(rèn)的一致。
總結(jié)
本文簡(jiǎn)要介紹了在小程序開發(fā)中如何適配 iPhone X 屏幕,更多細(xì)節(jié)請(qǐng)查閱我們?cè)?GitHub 上開源的知識(shí)小集小程序的代碼:awesome-tips-wx-app