iOS開發 iPhone X 適配及 safeArea 引起的一些問題

蘋果公司于2017年9月13日凌晨發布了兩款新的手機—— iPhon 8與iPhone X,作為全新的屏幕樣式 iPhone X 的適配問題也成了大家都很關注的一個問題。
以下通過官方文檔、項目中出現的問題、網上的資料來談談 iPhone X 的適配
一、官方文檔說明
布局
1、在 iPhone X 上預覽你的應用。你可以 Simulator(Xcode 附屬應用 )來預覽你的應用。請注意檢查應用元素是否被屏幕切割、布局是否正常等。對于一些新特性,比如廣色域顯示,使用實體設備才能起到最好的預覽效果。
2、為了更好的提供全屏使用體驗。 確保背景能夠延伸到屏幕邊緣,垂直滾動布局,如表單或集合頁需一直延續至屏幕底部。(親測使用系統提供的標準組件沒有問題)

屏幕快照 2017-10-10 下午5.32.35.png

3、插入必要內容以防止被裁切。一般來說,內容應該是居中對稱的,這樣在任何方向上都能獲得比較好的觀感,也不會被屏幕圓角、傳感器區域和主屏幕支持器所影響。為了保證最佳效果,請使用系統提供的標準控件和響應式布局來構建您的頁面。所有的應用都應該遵循 UIKit 定義的安全區域和布局邊距,這些區域可以根據設備的上下文進行適當的填充。同時,安全區可以防止你的內容覆蓋狀態欄、導航欄、工具欄和標簽欄。
4、注意狀態欄的高度。iPhone X 的狀態欄比其他 iPhone 上要更高一些。如果您的應用元素尺寸是根據狀態欄高度來判斷,或是元素位置處于狀態欄下方,則必須更新您的應用,請跟據用戶的設備來動態定位內容。請注意,當后臺任務(如錄音和位置跟蹤)處于活動狀態時,iPhone X上的狀態欄不會改變高度。
5、如果您的應用目前是隱藏狀態欄,請根據 iPhone X 屏幕特點重新考慮。iPhone X 的屏幕比 4.7 英寸 iPhone 的屏幕高很多,省去狀態欄占據的內容區域可能并不會得到很好的利用。狀態欄還展示了人們覺得有用的一些信息,請思考當你將它隱藏時換來的價值要高于顯示。

屏幕快照 2017-10-10 下午5.38.58.png

6、在重復使用現有圖稿時,請注意長寬比差異。iPhone X 與常規 iPhone 的屏幕長寬比不同,因此,全屏的 4.7 寸屏圖像在 iPhone X 上會出現裁切或適配寬度顯示。同理 iPhone X 的圖片在 4.7 寸屏上也會出現此情況。所以,重要的視覺稿請根據設備型號做相應的調整。
7、避免將可交互控件放在屏幕底部和角落。屏幕底部可以通過手勢進入主屏幕和多任務頁面,這些手勢可能會覆蓋您在此區域中實現的自定義手勢。屏幕角落可能無法讓人們舒適地觸達。
8、不要遮蓋或引導關注屏幕新特性的關鍵位置。不要使用放置黑色欄在屏幕上下區域等方式來試圖隱藏設備的圓角、傳感器區域和主頁指示器,也不要使用類似括號、輪廓、形狀和教學文案等視覺元素來引導用戶關注這些區域。
9、允許自動隱藏回到主屏幕指示器。當自動隱藏開啟時,用戶幾秒鐘不觸碰屏幕指示器便會漸隱消失。用戶觸碰屏幕后指示器再次顯示。此特性只能用于沉浸式預覽樣式,比如視頻播放或幻燈片樣式。
10、在橫屏狀態下官方給出的錯誤的設計樣式和正確的設計樣式

屏幕快照 2017-10-11 上午10.32.07.png
屏幕快照 2017-10-11 上午10.32.15.png

二、****iPhone X 屏幕變化總結
1、屏幕尺寸
5.15 英寸 458 ppi(ppi : 每英寸所擁有的像素(pixel)數目)
1125px × 2436px(75pt × 812pt @3x)
為了更好的突出 iPhone X 的屏幕顯示效果,請使用 3 倍圖
2、iPhone 7 和 iPhone X 對比:
如下圖所示,iPhone 7 設備渲染后分辨率為 750 x 1334,邏輯分辨率只有 375 x 667。iPhone X 設備渲染后分辨率為 1125 x 2436,邏輯分辨率是為 375 x 812。可以看出顯示區域寬度是相同的,但是高度多了 145pt

屏幕快照 2017-10-10 下午5.28.33.png

3、頂部多出傳感器區域(俗稱劉海),底部的實體 home 鍵消失,屏幕下方多出返回主頁指示器(網上有稱之為 homeBar 的,官方沒有明確命名,為了方便表達,以下內容稱之為 homeBar)屏幕四個角變成大圓角。官方文檔上表明:在你為 iPhone X 設計界面時,請必須保證所有設計內容不能被屏幕圓角、上方傳感器區域、下方返回主頁指示器所遮擋。

屏幕快照 2017-10-11 下午3.49.28.png

4、statusBar 的高度在 iPhone X 上變成了 44,其他設備都是 20。對于開發者來說,項目中隱藏導航欄,偏移量按照原來的 20 固定值來使用的,在屏幕上出現偏移。(對于 App 混合開發的項目,iOS 開發在開發中使用動態獲取的值進行計算,前端開發的同學適配的時候可以通過獲取手機型號來賦值)

屏幕快照 2017-10-10 下午5.33.30.png

5、tabBar 的高度在 iPhone X 上變成了 83,其他設備是 49,多出 34,多出的部分是給 homeBar 流出控件,可以算出 homeBar 的高度為 34。

屏幕快照 2017-10-10 下午5.29.46.png

三、適配**** iPhone X****的新特性
1、顏色
iPhone X 屏幕支持 P3 色彩空間,這意味著它將可以顯示更多的色彩,比 sRGB 要更加艷麗。
使用廣色域來提高視覺體驗。使用了廣色域的圖片和視頻會更加生動,使用廣色域的數據圖表和狀態指示器會更加有沖擊力。更多信息請查看「色彩管理」。

屏幕快照 2017-10-10 下午5.39.37.png

2、手勢
iPhone X 使用屏幕邊緣手勢來訪問主屏幕、應用切換、通知中心和控制用心。
避免干擾到系統級別的屏幕邊緣手勢。人們使用這些手勢來使用所有應用,在極少數情況下,像游戲這樣的沉浸式應用程序可能需要自定義的屏幕邊緣手勢。優先于系統的手勢:第一次滑動會調用自定義手勢,而第二次滑動則會調用系統手勢。這種自定義行為(稱為邊緣保護)應該謹慎使用,因為它使得用戶難以訪問系統級的操作。更多信息請查看「手勢」。
3、Face ID
iPhone X 支持 Face ID 進行身份驗證。如果您的應用程序與 Apple Pay 或其他系統身份驗證功能集成,請勿在 iPhone X 上引用 Touch ID。同樣,請不要在支持 Touch ID 的設備上引用Face ID。更多信息請查看「驗證」。

屏幕快照 2017-10-11 下午3.58.22.png

4、鍵盤功能
在 iPhone X 上,Emoji、語言切換和語音識別按鈕會自動顯示在鍵盤的下方(即使使用自定義鍵盤)。 您的應用程序不能影響這些按鈕,為了避免造成困擾,請不要在鍵盤中重復定義這些按鈕。

四、對于原有的項目,適配**** iPhone X ****可能會遇到的問題
1、App 頁面沒有完全充滿屏幕
原因:
UIScreen的初始化是根據我們進入的第一個頁面去進行參數化的
解決方式:
補上1125 x 2436的圖或采用 LaunchScreen.xib 或者 LaunchScreen.storyboard 進行配置啟動圖
2、下拉刷新被頭部劉海遮蓋
原因:
頭部劉海遮蓋住了刷新控件
解決:
增加刷新控件的高度
3、個人中心界面頭部導航欄問題
原因:
沒有使用系統的導航欄,自定義的導航欄導致高度增大
解決方式:
動態獲取導航欄高度作為自定義的導航欄高度
4、底部的按鈕和 homeBar 重合
原因:
status 的高度改變,造成按鈕和 Home 鍵重合
解決:
動態計算 frame 的值
(歡迎補充)

五、關于**** iOS11 ****新增新特性**** safeArea ****對項目造成的影響
在iOS11設備上運行出現最多問題應該就是 tableview 莫名奇妙的偏移 20pt 或者 64pt,原因就是iOS11棄用了 automaticallyAdjustsScrollViewInsets 屬性,新增了 UIScrollView 的 contentInsetAdjustmentBehavior 屬性,根本原因就是 iOS11 新引入的 safeArea 引起(個人認為這是 iPhone X 屏幕的大浮動變動引起的,為了 view 不被 statusBar、navigationBar、tabBar 遮住,更好的適配 iPhone X)
什么是安全區域呢?
如下圖,藍色區域為安全區域。系統認為 statusBar、navigationBar、tabBar 之外的區域為安全區域,對于 UIScrollView、UITableView、UICollectionView,系統會自動給他添加一個內邊距,造成偏移。即使把 navigationBar 設為透明,系統也認為安全區域是從 navigationbar 的 bottom 開始的。
比如:當你的APP中使用的是自定義的 navigationbar,隱藏掉系統的navigationbar,并且 tableView 的 frame 為 (0,0,SCREEN_WIDTH, SCREEN_HEIGHT) 開始,那么系統會自動調整SafeAreaInsets值為 (STATUS_BAR_HEIGHT,0,0,0),如果使用了系統的 navigationbar,那么 SafeAreaInsets 值為 (64,0,0,0),如果也使用了系統的 tabbar,那么 SafeAreaInsets 值為 (STATUS_BAR_HEIGHT + NAVI_BAR_HEIGHT, 0, TAB_BAR_HEIGHT, 0)。(SCREEN_WIDTH 表示屏幕寬,SCREEN_HEIGHT 表示屏幕高,STATUS_BAR_HEIGHT 表示狀態欄高度,NAVI_BAR_HEIGHT 表示導航欄高度,TAB_BAR_HEIGHT 表示底部選項卡高度)
官方定義:安全區域定義了view中可視區域的部分,保證不被系統的狀態欄、或父視圖提供的 view 如導航欄覆蓋。

屏幕快照 2017-10-10 下午5.55.55.png

當項目中出現莫名偏移的情況,可參考的解決方法:
1、根據取代 automaticallyAdjustsScrollViewInsets 屬性的 contentInsetAdjustmentBehavior 屬性

if (@available(iOS 11.0, *)) {
    self.webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    // 設置內邊距
    self.webView.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
    // 設置滾動條的內邊距
    self.webView.scrollView.scrollIndicatorInsets = self.webView.scrollView.contentInset;
} else {
    self.automaticallyAdjustsScrollViewInsets = false;
}

2、根據 iOS11 UIScrollView 新增的兩個屬性:adjustContentInset 和 contentInsetAdjustmentBehavior

if (@available(iOS 11.0, *)) {
    self.additionalSafeAreaInsets = UIEdgeInsetsMake(-STATUS_BAR_HEIGHT, 0, 0, 0);
    // 如果使用了 navigationBar,又把它隱藏的情況, additionalSafeAreaInsets 要找到使它偏移的 Controller
    // self.navigationController.additionalSafeAreaInsets = UIEdgeInsetsMake(--NAVI_BAR_HEIGHT, 0, 0, 0);
} else {
    self.automaticallyAdjustsScrollViewInsets = false;
}

關于scrollView在iOS11新增的兩個屬性 adjustContentInset 和 contentInsetAdjustmentBehavior:
adjustContentInset 表示 contentView.frame.origin 偏移了 scrollview.frame.origin 多少;
是系統計算得來的,計算方式由 contentInsetAdjustmentBehavior 決定。
有以下幾種計算方式:

  1. UIScrollViewContentInsetAdjustmentAutomatic: 如果 scrollview 在一個automaticallyAdjustsScrollViewInsets = YES的controller上,并且這個 Controller 包含在一個 navigation controller 中,這種情況下會設置在 top & bottom 上 adjustedContentInset = safeAreaInset + contentInset 不管是否滾動。其他情況下與UIScrollViewContentInsetAdjustmentScrollableAxes 相同;
  2. UIScrollViewContentInsetAdjustmentScrollableAxes: 在可滾動方向上adjustedContentInset = safeAreaInset + contentInset,在不可滾動方向上adjustedContentInset = contentInset;
    依賴于 scrollEnabled 和alwaysBounceHorizontal / vertical = YES,scrollEnabled 默認為 YES ,所以大多數情況下,計算方式還是 adjustedContentInset = safeAreaInset + contentInset
  3. UIScrollViewContentInsetAdjustmentNever: adjustedContentInset = contentInset
  4. UIScrollViewContentInsetAdjustmentAlways: adjustedContentInset = safeAreaInset + contentInset
    當 contentInsetAdjustmentBehavior 設置為UIScrollViewContentInsetAdjustmentNever 的時候,adjustContentInset 值不受 SafeAreaInset 值的影響。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,363評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,497評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,305評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,962評論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,727評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,193評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,411評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,945評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,777評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,978評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,216評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,657評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,960評論 2 373

推薦閱讀更多精彩內容