更多可查看官方文檔和視頻Creating apps for iPhone X.json
相信有一部分道友的APP在iPhone X上運行時並無像想象中那樣佔滿整個屏幕, 而是保持着原有的高度 在屏幕中心位置, 針對這個問題 目前通過實驗得出能夠經過如下方式使APP按照全屏模式運行:安全
LaunchScreen.storyboard
方式啓動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
iOS11爲UIViewController
和UIView
增長了兩個新的屬性safeAreaInsets
和safeAreaLayoutGuide
, 經過這兩個屬性咱們能夠得到安全區域的範圍, 經過上圖能夠很清楚的看到安全區域的範圍, 咱們要作的是讓那些不能被遮擋的內容和控件在安全區域範圍內顯示, 注意!這句話很是重要.工具
safeAreaInsets
適用於手動計算.safeAreaLayoutGuide
適用於自動佈局.通常來講 能夠經過在原有視圖座標計算時加入安全區域的範圍值, 下面舉個例子:佈局
一個APP 它的NavigationBar使用的是自定義的UIView
, 並不是UINavigationBar
, 這個自定義的UIView
的frame
屬性爲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 爲UIViewController
和UIView
增長了一個新的方法 - (void)viewSafeAreaInsetsDidChange;
這個方法如名字同樣 在安全區域改變後會被調用, 咱們能夠在須要適配的UIViewController
和UIView
中重寫這個方法, 而且在這個方法中來根據safeAreaInsets
屬性更新子視圖控件的佈局位置.
這裏有一點要注意的是當UIViewController
調用- (void)viewDidLoad
時它的全部子視圖的safeAreaInsets
屬性都等於UIEdgeInsetsZero
, 也就是說在- (void)viewSafeAreaInsetsDidChange;
方法調用前 是沒法經過當前視圖控制器的子視圖獲取到safeAreaInsets
的, 不過獲取當前window對象的safeAreaInsets
屬性用來計算也是能夠的, 可是不建議這麼作, 一個視圖控制器的子視圖的處理固然要以它所在的控制器爲準.
- (void)viewSafeAreaInsetsDidChange
在UIViewController
中第一次調用的時間是在- (void)viewWillAppear:(BOOL)animated
調用以後, 在- (void)viewWillLayoutSubviews
調用以前.
固然若是你要改變一個UIViewController
的safeAreaInsets
值, 能夠經過設置addtionalSafeAreaInsets
屬性來實現, 例如你要自定義一些特殊的樣式時.
若是你改變了一個UIViewController
的safeAreaInsets
屬性值, - (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
iOS11之前,咱們佈局時, 視圖的 top
和 bottom
通常參照的是 Top Layout Guide
和 Bottom Layout Guide
.
iOS11之後, 那兩個參照已經 deprecated
(過期)了, 而是被Safe Area
所取代.