關於iPhone X 的適配

1.屏幕尺寸相關變化

  1. 高度增長了145pt,變成812pt.
  2. 屏幕圓角顯示,注意至少留10pt邊距。
  3. 狀態欄高度由20pt變成44pt,留意這個距離就能避開「劉海」的尷尬,相應的導航欄以上變化64->88。
  4. 底部工具欄須要爲home indicator留出34pt邊距。
  5. 物理分辨率爲1125px * 2436px.

2.橫豎屏安全區對比

3.其餘設備安全區域對比

4.應用設計

5.控件佈局

更多可查看官方文檔和視頻Creating apps for iPhone X.json

如何讓APP適配?

APP啓動樣式適配

相信有一部分道友的APP在iPhone X上運行時並無像想象中那樣佔滿整個屏幕, 而是保持着原有的高度 在屏幕中心位置, 針對這個問題 目前通過實驗得出能夠經過如下方式使APP按照全屏模式運行:安全

  1. 經過LaunchScreen.storyboard方式啓動
  2. 若是使用的是Assets中的LaunchImage, 在增長了iPhone X尺寸的圖片配置後.

LaunchScreen.storyboard方式不用多說, 這裏說一下如何在LaunchImage中增長iPhone X尺寸的圖片配置.app

準備一張尺寸:1125 * 2436的啓動圖片, 移動到LaunchImage的Finder目錄中, 並在LaunchImage中的Contents.json文件中增長 (注意Json格式):iphone

{
    "extent" : "full-screen",
    "idiom" : "iphone",
    "subtype" : "2436h",
    "filename" : "圖片名.png",
    "minimum-system-version" : "11.0",
    "orientation" : "portrait",
    "scale" : "3x"
}

按照以上方式配置就徹底解決了這個問題.ide

APP內部樣式適配

iOS11爲UIViewControllerUIView增長了兩個新的屬性safeAreaInsetssafeAreaLayoutGuide, 經過這兩個屬性咱們能夠得到安全區域的範圍, 經過上圖能夠很清楚的看到安全區域的範圍, 咱們要作的是讓那些不能被遮擋的內容和控件在安全區域範圍內顯示, 注意!這句話很是重要.工具

  • safeAreaInsets 適用於手動計算.
  • safeAreaLayoutGuide 適用於自動佈局.

Frame佈局方式適配示例

通常來講 能夠經過在原有視圖座標計算時加入安全區域的範圍值, 下面舉個例子:佈局

一個APP 它的NavigationBar使用的是自定義的UIView, 並不是UINavigationBar, 這個自定義的UIViewframe屬性爲CGRectMake(0, 0, 375, 64).
這樣的UIView在其餘設備上是沒有問題的, 標準的導航欄尺寸, 可是若是運行在iPhone X上 你會發現看上去無比的彆扭, 由於異形屏幕會形成部分顯示內容的遮擋問題, 這時候就要用到安全區域這個概念來解決這一問題.ui

先說一說一般自定義導航欄的結構, 高度是爲64 由44高度的導航欄內容區域和20高度的狀態欄區域(電池條那部分 status bar)組成, 44高度的導航欄內容區域用來顯示導航欄上的控件, 如返回按鈕 標題視圖等等, 如今, 在iPhone X上, 原來的狀態欄(status bar)高度再也不考慮了, 取而代之的是安全區域頂部間距safeAreaInsets.top, 咱們將原有的結構改成 安全區域頂部距離屏幕的距離safeAreaInsets.top + 導航欄內容區域44, 這樣完成了一個自定義導航欄視圖在iPhone X上的適配.設計

下面是適配先後的效果對比:3d

再來看一下適配後的自定義導航欄視圖的UI結構

這只是舉一個簡單的例子, 由於不一樣的應用設計都是不一樣的, 可是適配的思路都是同樣的, 仍是那句話 咱們要作的是讓那些不能被遮擋的內容和控件在安全區域範圍內顯示, 在計算佈局時 將安全區域這個新特性考慮進去, iPhone X的適配也不是難事.

說一下在代碼中的安全區域的適配該如何去寫:

iOS11 爲UIViewControllerUIView增長了一個新的方法 - (void)viewSafeAreaInsetsDidChange;

這個方法如名字同樣 在安全區域改變後會被調用, 咱們能夠在須要適配的UIViewControllerUIView中重寫這個方法, 而且在這個方法中來根據safeAreaInsets屬性更新子視圖控件的佈局位置.

這裏有一點要注意的是當UIViewController調用- (void)viewDidLoad時它的全部子視圖的safeAreaInsets屬性都等於UIEdgeInsetsZero, 也就是說在- (void)viewSafeAreaInsetsDidChange;方法調用前 是沒法經過當前視圖控制器的子視圖獲取到safeAreaInsets的, 不過獲取當前window對象的safeAreaInsets屬性用來計算也是能夠的, 可是不建議這麼作, 一個視圖控制器的子視圖的處理固然要以它所在的控制器爲準.

- (void)viewSafeAreaInsetsDidChangeUIViewController中第一次調用的時間是在- (void)viewWillAppear:(BOOL)animated調用以後, 在- (void)viewWillLayoutSubviews調用以前.

固然若是你要改變一個UIViewControllersafeAreaInsets值, 能夠經過設置addtionalSafeAreaInsets屬性來實現, 例如你要自定義一些特殊的樣式時.

若是你改變了一個UIViewControllersafeAreaInsets屬性值, - (void)viewSafeAreaInsetsDidChange也會被調用.

另外, 給道友們的分享一個獲取某View安全區域範圍的宏

#define VIEWSAFEAREAINSETS(view) ({UIEdgeInsets i; if(@available(iOS 11.0, *)) {i = view.safeAreaInsets;} else {i = UIEdgeInsetsZero;} i;})

使用起來比較簡潔

VIEWSAFEAREAINSETS(view).left

VIEWSAFEAREAINSETS(self.view).right

AutoLayout佈局方式示例

iOS11之前,咱們佈局時, 視圖的 top 和 bottom 通常參照的是 Top Layout Guide 和 Bottom Layout Guide.

iOS11之後, 那兩個參照已經 deprecated (過期)了, 而是被Safe Area所取代.

參考自官方文檔

相關文章
相關標籤/搜索