[貝聊科技]貝聊 iPhone X 適配實戰

貝聊科技發表於2017-11-02

@NewPan 貝聊科技 iOS 菜鳥工程師

這款為天貓定製的 iPhone,你買了嗎?由於沒摸過真機,所以嚴格意義上來說,這篇文章應該有一個更加接地氣的名字:“模擬器適配實戰”。

01.適配原則

由於這篇文章是實戰,就不巴拉巴拉說適配思想安全區域的概念了,不懂的可以去看蘋果官方的 《為 iPhone X 更新您的 app》

上面那篇文章是中文版,而且下面還有三個帶中文字幕的視訊,從設計、編碼和原理三個角度告訴你怎麼樣是適配 iPhone X。注意,Designing for iPhone X 這個視訊,一般的設計師是看不懂的,所以這個視訊雖說是設計知識,但是其實是給開發人員看的。所以最好是我們開發人員看了講給 UI 設計師聽,告訴他們怎麼適配。

02.啟動頁適配

如果你是第一次下載 Xcode 9,執行起來,APP 並沒有完全填充整個模擬器,這時你需要 UI 設計師給你切一張新的啟動圖,圖片尺寸應該和 iPhone X 一樣,iPhone X 的螢幕尺寸為 375 * 812 pt,記得 iPhone X 的螢幕是 @3x 的。

這裡還有一個細節,拿到這張 iPhone X 啟動圖以後在你的專案裡找到 Assets.xcassets 裡的 LaunchImage,但是並沒有放 iPhone X 啟動圖的位置,此時,你應該先把之前的啟動圖複製一份,然後將舊的 LaunchImage 刪除,然後右鍵重新建立一個 LaunchImage,此時,你就可以看到 iPhone X 啟動圖的位置了。

03.啟動頁廣告設計

之前所有的廣告頁面設計都是按照 iPhone 6s 的螢幕標準來設計的,這在沒有 iPhone X 的時代是沒有問題的。現在有了 iPhone X,它的螢幕比例不是 16 :9,所以這個廣告頁面放到 iPhone X 上就會出現左右被裁掉。但是如果按照 iPhone X 的螢幕來設計,就會導致在非 iPhone X 上顯示出現上下被截掉的情況。

因此我們採取的方法是,仍然使用 iPhone 6s 的螢幕來進行設計,只是設計師注意在左右留出一部分距離,保證在 iPhone X 上顯示把左右裁掉一部分以後依然能夠正常顯示。

04.safeAreaInsets 使用的坑

我們公司的專案的絕大部分介面都是用程式碼寫的,沒有使用 SB 或者 xib,而且舊程式碼佈局沒有規範,並沒有寫在 -viewWillLayoutSubviews: 中。

上面的官方示例程式碼也告訴我們要相對 safeAreaInsets 進行佈局,確保我們的介面是使用者(老闆)友好的。但是這個屬性在 -viewDidLoad:-viewWillAppear: 方法中都是為 UIEdgeInsetsZreo,第一次有值是 -viewWillLayoutSubviews:。而且這個值在 -viewWillLayoutSubviews: 的幾次呼叫中會不停地修正。

其實文件裡有寫這個屬性的註釋:
If the view is not currently installed in a view hierarchy, or is not yet visible onscreen, the edge insets in this property are 0. 假如當前 view 沒有佈局到視窗的中,這個值就是 0。

這給我們修改舊程式碼帶來極大的不便,我們不太可能把舊程式碼寫在 -viewDidLoad: 中的所有的佈局程式碼都挪到 -viewWillLayoutSubviews: 中去,尤其對於全部是是手寫佈局的這種情況。

所以我們需要一種更加靈活有效的方式,對於某個狀態列、導航欄和標籤欄固定顯示的介面,它的 statusBarnavigationBartabBarframe 都是一個的固定值。因為我們是在 -viewDidLoad: 中修改舊的佈局,此時 -viewDidLoad: 中拿到的 safeAreaInsets 是無效的,但是我們就可以跳過 safeAreaInsets,直接使用 statusBarnavigationBartabBar 的高度來求得安全區域,然後將我們的介面佈局在我們自己用上面三個元素的高度構建的安全區域內。

這樣我們就可以以追求最小的程式碼改動為原則來適配 iPhone X。

05.tableView 適配

tableView 系統都幫我們適配好了,真的沒什麼可講的。如果一定要講就是有些介面我們需要把 tableViewcontentInsetAdjustmentBehavior 這個屬性給設定為 .never。當這樣做以後,我們就無法享受系統自動優化 tableView 的一個便利,這個便利就是系統幫我們把 tableView 的內容上下都插入一個安全區域大小的額外滾動距離來使介面使用者友好,因此我們需要手動插入 contentInsets 來保證這一點。

06.橫屏適配

國內 iPhone 應用絕大多數都不支援橫屏,當然也有例外,如果一個應用涉及到視訊,不管是播放視訊還是錄製視訊,大多數情況下都需要在某些介面小範圍支援橫屏。如果你有橫屏的問題,可以參考我另外一篇文章,關於在只支援豎屏的應用中小範圍支援橫屏的一個實踐:[iOS]終極橫豎屏切換解決方案

我們的專案中也有橫屏頁面,是我們的直播頁面。橫屏適配的原則就是要讓所有的元素都佈局到安全區域內,此時我們是要依靠 safeAreaInsets 來確定底部的安全區域高度。如果你的專案中有橫屏的 tableView,那你應該看一下上面的視訊,視訊裡有詳細的介紹蘋果如何使 WWDC 這個應用在 iPhone X 上支援橫屏。

07.網頁適配

網頁底部可能會有些需要互動的元素,如果不做任何處理就會被黑線擋住。由於舊網頁設計的時候沒有在底部留出對應的空隙,所以,我們只能用程式碼處理了。好在 UIWebView 有一個 scrollView 的屬性,我們可以方便的給 UIWebView 在底部新增一個安全滾動距離,雖然對於有底色的網頁,這種方案並不優雅,但是眼下也只能這樣了。

但是這只是過渡的方案,以後的 UI 設計上還是應該儘量照顧到 iPhone X,留出 34 的高度來保證使用者體驗。

08.聯動動畫

大家的專案裡肯定少不了類似這樣的動畫。這個動畫不容易,在 -scrollViewDidScroll: 裡算各種參與動畫的元素的 frame,然後計算動畫觸發臨界位置,做完一次以後再也不想做第二次了。

然後跑到 iPhone X 上一看,位置全錯。沒辦法,只能重頭來一次了唄,這又沒有什麼捷徑可走,只能先將元素起始位置相對於安全區域佈局好,然後再計算終點位置的佈局,中間過渡不就很簡單了嗎?

09.第三方庫適配

佈局使用的 Masonry 已經支援相對安全區域佈局。ASDK 也已經支援,只需要將 SDK 更新一下就可以了。

我的文章集合

下面這個連結是我所有文章的一個集合目錄。這些文章凡是涉及實現的,每篇文章中都有 Github 地址,Github 上都有原始碼。如果某篇文章剛好在你的實際開發中幫到你,又或者提供一種不同的實現思路,讓你覺得有用,那就看看這句話 “堅持每天點讚的人,99%都是帥哥美女,再也不用單身了”。

我的文章集合索引

你還可以關注我自己維護的簡書專題 iOS開發心得。這個專題的文章都是實打實的乾貨。

如果你有問題,除了在文章最後留言,還可以在微博 @盼盼_HKbuy上給我留言,以及訪問我的 Github

相關文章