本文主要介紹我們的知識小集小程序在適配 iPhone X 屏幕時遇到的一些問題以及總結(jié),希望對你的小程序開發(fā)能有所幫助。 iPhone X 屏幕數(shù)據(jù)在去年 9 月份 iPhone X 正式發(fā)布后,引發(fā)了一波 iOS App 適配 iPhone X 的熱潮和技術文章,詳情可以參考掘金技術社區(qū)的這個專題: 《iPhone X 適配實踐》 我們這里先簡單總結(jié)一下 iPhone X 屏幕的基礎數(shù)據(jù),方便后續(xù)在小程序開發(fā)中進行適配。
此外,由于在 iPhone X 屏幕頂部狀態(tài)欄區(qū)域有“齊劉海”,以及在屏幕底部增加了“操作條”,如下圖所示,因此,我們在開發(fā)中需要注意 安全區(qū)域 的問題。
根據(jù)蘋果官方的文檔,iPhone X 頂部狀態(tài)欄的適配安全區(qū)域的高度為 44pt,底部操作條區(qū)域的高度為 34pt。另外,在 iPhone X 中,一些系統(tǒng) Bar 的默認高度相比于之前的設備也發(fā)生了變化,如下表所示。
所以在 iOS App 開發(fā)中,如果我們使用系統(tǒng)默認的 UINavigationController 和 UITabBarController 時,則無需額外的適配工作,iOS 系統(tǒng)會自動適配好相關 Bar 的安全區(qū)域問題。如果我們使用了自定義的導航欄和標簽欄,則需要注意根據(jù)設備類型區(qū)分設置這些 Bar 的不同高度。 小程序的尺寸單位為了解決不同屏幕尺寸的適配問題,小程序自己定了一個尺寸單位:rpx(responsive pixel),它可以根據(jù)屏幕寬度進行自適應。小程序中規(guī)定, 所有設備的屏幕寬度都為 750rpx ,根據(jù)設備屏幕實際寬度的不同,1rpx 所代表的實際像素值也不一樣。 根據(jù) 微信開發(fā)文檔 ,在 4.7 英寸的 iPhone 設備上(iPhone 6/7/8),屏幕寬度為 375px(此處應該理解為 375 point),共有 750 個物理像素,則 750rpx = 375px = 750 物理像素,1rpx = 0.5px = 1物理像素。
小程序中如何判斷設備為 iPhone X上面我們簡要介紹了 iPhone X 的屏幕數(shù)據(jù)和小程序中的尺寸單位作為鋪墊,現(xiàn)在終于要切入正題了,要在小程序中適配 iPhone X 屏幕,首先我們需要知道如何判斷設備類型。 微信的小程序 API 中提供了一個 wx.getSystemInfo(OBJECT) 方法用于獲取用戶手機的系統(tǒng)信息和設備信息,包含如下數(shù)據(jù):
上述每個字段的含義詳見 文檔 ,我們不再一一贅述。 因此,我們可以根據(jù)該方法返回的手機型號字段 model 是否包含 iPhone X 字符串來判斷設備是否為 iPhone X,也可以根據(jù) screenHeight 的高度是否等于 812 來判斷。 NOTE:這里有一個小坑需要注意,在微信開發(fā)者工具中的模擬器,如果選擇為 iPhone X,此時獲取到的 model 值為 iPhone X ,導致我以為真機也是這個值,于是直接用 if (model == 'iPhone X') 來判斷,但其實真機下 model 的值為這種格式: iPhone X (GSM+CDMA)<iPhone10,3> ,因此我們需要用字符串檢索匹配進行判斷。 綜上,我們可以在 app.js 的 globalData 中添加一個字段 isIPX 用于標識當前設備是否為 iPhone X,然后在小程序啟動時 onLaunch 中調(diào)用 wx.getSystemInfo(OBJECT) 方法并在其 success回調(diào)中讀取 model 字段進行分析,代碼大致如下: App({ // 全局數(shù)據(jù) globalData: { // 其他數(shù)據(jù)定義 ... isIPX: false, // 當前設備是否為 iPhone X }, // 小程序啟動入口 onLaunch: function (options) { // 其他啟動代碼... // 判斷設備是否為 iPhone X this.checkIsIPhoneX() }, checkIsIPhoneX: function() { const self = this wx.getSystemInfo({ success: function (res) { // 根據(jù) model 進行判斷 if (res.model.search('iPhone X') != -1) { self.globalData.isIPX = true } // 或者根據(jù) screenHeight 進行判斷 // if (res.screenHeight == 812) { // self.globalData.isIPX = true // } } }) }, } 如果需要小程序啟動時立即獲取設備相關信息,也可以調(diào) wx.getSystemInfoSync() 方法,它會同步獲取數(shù)據(jù)并立即返回。 頁面適配實戰(zhàn)在小程序頁面開發(fā)中,涉及到需要適配 iPhone X 的地方主要有:導航欄(NavigationBar),標簽欄(TabBar)以及頁面底部的吸底按鈕。
如果我們使用微信小程序官方組件進行開發(fā),沒有進行自定義,在 app.json 文件中設置 tabBar 頁面,且 window 的 navigationStyle 值為 default ,那么我們無需在 iPhone X 中對導航欄和標簽欄進行適配,微信會自動幫我們適配好,如下圖為知識小集小程序的首頁:
但是我們?nèi)绻亲远x導航欄(在 app.json 文件中設置 window 的 navigationStyle 為 custom ,此時只保留右上角膠囊狀的按鈕,需要開發(fā)者自己畫導航欄樣式)和標簽欄,則我們需要在每個頁面中判斷設備類型,并針對 iPhone X 屏幕在安全區(qū)域內(nèi)進行布局,并修改相關 Bar 的高度值(見上述表格)。 以自定義導航欄適配為例,步驟如下: (1)在每個頁面的 page.js 中先讀取 app.js 中的 isIPX 值,如下: const app = getApp() Page({ data: { // 頁面其他數(shù)據(jù)... isIPX: app.globalData.isIPX, }, // 其他代碼 } (2)然后在 page.wxss 樣式文件中對某一個視圖 View 分別為普通屏幕和 iPhone X 屏幕寫兩種樣式,如下: .navi-bar-view { height: 64px; /* 其他樣式值 */ } .navi-bar-view-IPX { height: 88px; /* 其他樣式值 */ } (3)最后在 page.wxml 頁面結(jié)構(gòu)布局中根據(jù) isIPX 的值給 View 設置不同的 class 樣式,如下: <view class="{{isIPX ? 'navi-bar-view-IPX' : 'navi-bar-view'}}"> </view> 此外,對于自定義導航欄和標簽欄,我建議還是要遵循 iPhone UI 的設計規(guī)范,樣式可以參考蘋果官方的渲染圖:
在小程序頁面中,吸底按鈕是很常見的一種設計,我們一般會把一些重要的按鈕放在頁面底部懸浮不動,例如我們知識小集小程序的“小集詳情頁”底部的“收藏”和“轉(zhuǎn)發(fā)”按鈕:
在 iPhone X 中我們需要把吸底按鈕往上偏移 34 像素,可通過在 CSS 樣式中設置 padding-bottom 為 34px 實現(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> 備注:如前面所述,對于不同設備寬度,1rpx 所代表的實際像素值也不一樣,而在不同尺寸的 iPhone 設備(3.5/4.0/4.7/5.5 英寸)中,雖然它們的寬度不同,但其導航欄+狀態(tài)欄的高度都為 64pt(iPhone X 為 88pt),標簽欄 TabBar 的高度都為 49pt(iPhone X 為 83pt)。所以在小程序開發(fā)中,當我們需要自定義導航欄、標簽欄,或者適配 iPhone X 頂部和底部安全區(qū)域時,我建議此處的單位直接使用 px (在小程序中對應 iOS 開發(fā)中的點 pt )而不使用 rpx (當然頁面的其他元素的尺寸描述還是推薦使用 rpx ),以確保最終渲染顯示的高度與 iOS 系統(tǒng)默認的一致。 |