蘋果公司于2017年9月13日凌晨發(fā)布了兩款新的手機—— iPhon 8與iPhone X渔扎,作為全新的屏幕樣式 iPhone X 的適配問題也成了大家都很關(guān)注的一個問題装畅。
以下通過官方文檔雕欺、項目中出現(xiàn)的問題人芽、網(wǎng)上的資料來談?wù)?iPhone X 的適配
一裆熙、官方文檔說明
布局
1枫攀、在 iPhone X 上預(yù)覽你的應(yīng)用。你可以 Simulator(Xcode 附屬應(yīng)用 )來預(yù)覽你的應(yīng)用芽唇。請注意檢查應(yīng)用元素是否被屏幕切割顾画、布局是否正常等取劫。對于一些新特性,比如廣色域顯示研侣,使用實體設(shè)備才能起到最好的預(yù)覽效果谱邪。
2、為了更好的提供全屏使用體驗庶诡。 確保背景能夠延伸到屏幕邊緣惦银,垂直滾動布局,如表單或集合頁需一直延續(xù)至屏幕底部末誓。(親測使用系統(tǒng)提供的標(biāo)準(zhǔn)組件沒有問題)
3扯俱、插入必要內(nèi)容以防止被裁切。一般來說喇澡,內(nèi)容應(yīng)該是居中對稱的迅栅,這樣在任何方向上都能獲得比較好的觀感,也不會被屏幕圓角晴玖、傳感器區(qū)域和主屏幕支持器所影響读存。為了保證最佳效果,請使用系統(tǒng)提供的標(biāo)準(zhǔn)控件和響應(yīng)式布局來構(gòu)建您的頁面呕屎。所有的應(yīng)用都應(yīng)該遵循 UIKit 定義的安全區(qū)域和布局邊距让簿,這些區(qū)域可以根據(jù)設(shè)備的上下文進(jìn)行適當(dāng)?shù)奶畛洹M瑫r秀睛,安全區(qū)可以防止你的內(nèi)容覆蓋狀態(tài)欄尔当、導(dǎo)航欄、工具欄和標(biāo)簽欄蹂安。
4椭迎、注意狀態(tài)欄的高度。iPhone X 的狀態(tài)欄比其他 iPhone 上要更高一些藤抡。如果您的應(yīng)用元素尺寸是根據(jù)狀態(tài)欄高度來判斷侠碧,或是元素位置處于狀態(tài)欄下方抹估,則必須更新您的應(yīng)用缠黍,請跟據(jù)用戶的設(shè)備來動態(tài)定位內(nèi)容。請注意药蜻,當(dāng)后臺任務(wù)(如錄音和位置跟蹤)處于活動狀態(tài)時瓷式,iPhone X上的狀態(tài)欄不會改變高度。
5语泽、如果您的應(yīng)用目前是隱藏狀態(tài)欄贸典,請根據(jù) iPhone X 屏幕特點重新考慮。iPhone X 的屏幕比 4.7 英寸 iPhone 的屏幕高很多踱卵,省去狀態(tài)欄占據(jù)的內(nèi)容區(qū)域可能并不會得到很好的利用廊驼。狀態(tài)欄還展示了人們覺得有用的一些信息据过,請思考當(dāng)你將它隱藏時換來的價值要高于顯示。
6妒挎、在重復(fù)使用現(xiàn)有圖稿時绳锅,請注意長寬比差異。iPhone X 與常規(guī) iPhone 的屏幕長寬比不同酝掩,因此鳞芙,全屏的 4.7 寸屏圖像在 iPhone X 上會出現(xiàn)裁切或適配寬度顯示。同理 iPhone X 的圖片在 4.7 寸屏上也會出現(xiàn)此情況期虾。所以原朝,重要的視覺稿請根據(jù)設(shè)備型號做相應(yīng)的調(diào)整。
7镶苞、避免將可交互控件放在屏幕底部和角落喳坠。屏幕底部可以通過手勢進(jìn)入主屏幕和多任務(wù)頁面,這些手勢可能會覆蓋您在此區(qū)域中實現(xiàn)的自定義手勢茂蚓。屏幕角落可能無法讓人們舒適地觸達(dá)丙笋。
8、不要遮蓋或引導(dǎo)關(guān)注屏幕新特性的關(guān)鍵位置煌贴。不要使用放置黑色欄在屏幕上下區(qū)域等方式來試圖隱藏設(shè)備的圓角御板、傳感器區(qū)域和主頁指示器,也不要使用類似括號牛郑、輪廓怠肋、形狀和教學(xué)文案等視覺元素來引導(dǎo)用戶關(guān)注這些區(qū)域。
9淹朋、允許自動隱藏回到主屏幕指示器笙各。當(dāng)自動隱藏開啟時,用戶幾秒鐘不觸碰屏幕指示器便會漸隱消失础芍。用戶觸碰屏幕后指示器再次顯示杈抢。此特性只能用于沉浸式預(yù)覽樣式,比如視頻播放或幻燈片樣式仑性。
10惶楼、在橫屏狀態(tài)下官方給出的錯誤的設(shè)計樣式和正確的設(shè)計樣式
二、****iPhone X 屏幕變化總結(jié)
1诊杆、屏幕尺寸
5.15 英寸 458 ppi(ppi : 每英寸所擁有的像素(pixel)數(shù)目)
1125px × 2436px(75pt × 812pt @3x)
為了更好的突出 iPhone X 的屏幕顯示效果歼捐,請使用 3 倍圖
2、iPhone 7 和 iPhone X 對比:
如下圖所示晨汹,iPhone 7 設(shè)備渲染后分辨率為 750 x 1334豹储,邏輯分辨率只有 375 x 667。iPhone X 設(shè)備渲染后分辨率為 1125 x 2436淘这,邏輯分辨率是為 375 x 812剥扣」剩可以看出顯示區(qū)域?qū)挾仁窍嗤模歉叨榷嗔?145pt
3钠怯、頂部多出傳感器區(qū)域(俗稱劉海)球及,底部的實體 home 鍵消失,屏幕下方多出返回主頁指示器(網(wǎng)上有稱之為 homeBar 的呻疹,官方?jīng)]有明確命名吃引,為了方便表達(dá),以下內(nèi)容稱之為 homeBar)屏幕四個角變成大圓角刽锤。官方文檔上表明:在你為 iPhone X 設(shè)計界面時镊尺,請必須保證所有設(shè)計內(nèi)容不能被屏幕圓角、上方傳感器區(qū)域并思、下方返回主頁指示器所遮擋庐氮。
4、statusBar 的高度在 iPhone X 上變成了 44宋彼,其他設(shè)備都是 20弄砍。對于開發(fā)者來說,項目中隱藏導(dǎo)航欄输涕,偏移量按照原來的 20 固定值來使用的音婶,在屏幕上出現(xiàn)偏移。(對于 App 混合開發(fā)的項目莱坎,iOS 開發(fā)在開發(fā)中使用動態(tài)獲取的值進(jìn)行計算衣式,前端開發(fā)的同學(xué)適配的時候可以通過獲取手機型號來賦值)
5、tabBar 的高度在 iPhone X 上變成了 83檐什,其他設(shè)備是 49碴卧,多出 34,多出的部分是給 homeBar 流出控件乃正,可以算出 homeBar 的高度為 34住册。
三、適配**** iPhone X****的新特性
1瓮具、顏色
iPhone X 屏幕支持 P3 色彩空間荧飞,這意味著它將可以顯示更多的色彩,比 sRGB 要更加艷麗搭综。
使用廣色域來提高視覺體驗垢箕。使用了廣色域的圖片和視頻會更加生動,使用廣色域的數(shù)據(jù)圖表和狀態(tài)指示器會更加有沖擊力兑巾。更多信息請查看「色彩管理」。
2忠荞、手勢
iPhone X 使用屏幕邊緣手勢來訪問主屏幕蒋歌、應(yīng)用切換帅掘、通知中心和控制用心。
避免干擾到系統(tǒng)級別的屏幕邊緣手勢堂油。人們使用這些手勢來使用所有應(yīng)用修档,在極少數(shù)情況下,像游戲這樣的沉浸式應(yīng)用程序可能需要自定義的屏幕邊緣手勢府框。優(yōu)先于系統(tǒng)的手勢:第一次滑動會調(diào)用自定義手勢吱窝,而第二次滑動則會調(diào)用系統(tǒng)手勢。這種自定義行為(稱為邊緣保護)應(yīng)該謹(jǐn)慎使用迫靖,因為它使得用戶難以訪問系統(tǒng)級的操作院峡。更多信息請查看「手勢」。
3系宜、Face ID
iPhone X 支持 Face ID 進(jìn)行身份驗證照激。如果您的應(yīng)用程序與 Apple Pay 或其他系統(tǒng)身份驗證功能集成,請勿在 iPhone X 上引用 Touch ID盹牧。同樣俩垃,請不要在支持 Touch ID 的設(shè)備上引用Face ID。更多信息請查看「驗證」汰寓。
4口柳、鍵盤功能
在 iPhone X 上,Emoji有滑、語言切換和語音識別按鈕會自動顯示在鍵盤的下方(即使使用自定義鍵盤)啄清。 您的應(yīng)用程序不能影響這些按鈕,為了避免造成困擾俺孙,請不要在鍵盤中重復(fù)定義這些按鈕辣卒。
四、對于原有的項目睛榄,適配**** iPhone X ****可能會遇到的問題
1荣茫、App 頁面沒有完全充滿屏幕
原因:
UIScreen的初始化是根據(jù)我們進(jìn)入的第一個頁面去進(jìn)行參數(shù)化的
解決方式:
補上1125 x 2436的圖或采用 LaunchScreen.xib 或者 LaunchScreen.storyboard 進(jìn)行配置啟動圖
2、下拉刷新被頭部劉海遮蓋
原因:
頭部劉海遮蓋住了刷新控件
解決:
增加刷新控件的高度
3场靴、個人中心界面頭部導(dǎo)航欄問題
原因:
沒有使用系統(tǒng)的導(dǎo)航欄啡莉,自定義的導(dǎo)航欄導(dǎo)致高度增大
解決方式:
動態(tài)獲取導(dǎo)航欄高度作為自定義的導(dǎo)航欄高度
4、底部的按鈕和 homeBar 重合
原因:
status 的高度改變旨剥,造成按鈕和 Home 鍵重合
解決:
動態(tài)計算 frame 的值
(歡迎補充)
五咧欣、關(guān)于**** iOS11 ****新增新特性**** safeArea ****對項目造成的影響
在iOS11設(shè)備上運行出現(xiàn)最多問題應(yīng)該就是 tableview 莫名奇妙的偏移 20pt 或者 64pt,原因就是iOS11棄用了 automaticallyAdjustsScrollViewInsets 屬性轨帜,新增了 UIScrollView 的 contentInsetAdjustmentBehavior 屬性魄咕,根本原因就是 iOS11 新引入的 safeArea 引起(個人認(rèn)為這是 iPhone X 屏幕的大浮動變動引起的,為了 view 不被 statusBar蚌父、navigationBar哮兰、tabBar 遮住毛萌,更好的適配 iPhone X)
什么是安全區(qū)域呢?
如下圖喝滞,藍(lán)色區(qū)域為安全區(qū)域阁将。系統(tǒng)認(rèn)為 statusBar、navigationBar右遭、tabBar 之外的區(qū)域為安全區(qū)域做盅,對于 UIScrollView、UITableView窘哈、UICollectionView吹榴,系統(tǒng)會自動給他添加一個內(nèi)邊距,造成偏移宵距。即使把 navigationBar 設(shè)為透明腊尚,系統(tǒng)也認(rèn)為安全區(qū)域是從 navigationbar 的 bottom 開始的。
比如:當(dāng)你的APP中使用的是自定義的 navigationbar满哪,隱藏掉系統(tǒng)的navigationbar婿斥,并且 tableView 的 frame 為 (0,0,SCREEN_WIDTH, SCREEN_HEIGHT) 開始,那么系統(tǒng)會自動調(diào)整SafeAreaInsets值為 (STATUS_BAR_HEIGHT,0,0,0)哨鸭,如果使用了系統(tǒng)的 navigationbar民宿,那么 SafeAreaInsets 值為 (64,0,0,0),如果也使用了系統(tǒng)的 tabbar像鸡,那么 SafeAreaInsets 值為 (STATUS_BAR_HEIGHT + NAVI_BAR_HEIGHT, 0, TAB_BAR_HEIGHT, 0)活鹰。(SCREEN_WIDTH 表示屏幕寬,SCREEN_HEIGHT 表示屏幕高,STATUS_BAR_HEIGHT 表示狀態(tài)欄高度,NAVI_BAR_HEIGHT 表示導(dǎo)航欄高度系奉,TAB_BAR_HEIGHT 表示底部選項卡高度)
官方定義:安全區(qū)域定義了view中可視區(qū)域的部分蜂筹,保證不被系統(tǒng)的狀態(tài)欄竞阐、或父視圖提供的 view 如導(dǎo)航欄覆蓋。
當(dāng)項目中出現(xiàn)莫名偏移的情況,可參考的解決方法:
1、根據(jù)取代 automaticallyAdjustsScrollViewInsets 屬性的 contentInsetAdjustmentBehavior 屬性
if (@available(iOS 11.0, *)) {
self.webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
// 設(shè)置內(nèi)邊距
self.webView.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
// 設(shè)置滾動條的內(nèi)邊距
self.webView.scrollView.scrollIndicatorInsets = self.webView.scrollView.contentInset;
} else {
self.automaticallyAdjustsScrollViewInsets = false;
}
2桑涎、根據(jù) 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;
}
關(guān)于scrollView在iOS11新增的兩個屬性 adjustContentInset 和 contentInsetAdjustmentBehavior:
adjustContentInset 表示 contentView.frame.origin 偏移了 scrollview.frame.origin 多少攻冷;
是系統(tǒng)計算得來的,計算方式由 contentInsetAdjustmentBehavior 決定遍希。
有以下幾種計算方式:
- UIScrollViewContentInsetAdjustmentAutomatic: 如果 scrollview 在一個automaticallyAdjustsScrollViewInsets = YES的controller上等曼,并且這個 Controller 包含在一個 navigation controller 中,這種情況下會設(shè)置在 top & bottom 上 adjustedContentInset = safeAreaInset + contentInset 不管是否滾動。其他情況下與UIScrollViewContentInsetAdjustmentScrollableAxes 相同涉兽;
- UIScrollViewContentInsetAdjustmentScrollableAxes: 在可滾動方向上adjustedContentInset = safeAreaInset + contentInset招驴,在不可滾動方向上adjustedContentInset = contentInset篙程;
依賴于 scrollEnabled 和alwaysBounceHorizontal / vertical = YES枷畏,scrollEnabled 默認(rèn)為 YES ,所以大多數(shù)情況下虱饿,計算方式還是 adjustedContentInset = safeAreaInset + contentInset - UIScrollViewContentInsetAdjustmentNever: adjustedContentInset = contentInset
- UIScrollViewContentInsetAdjustmentAlways: adjustedContentInset = safeAreaInset + contentInset
當(dāng) contentInsetAdjustmentBehavior 設(shè)置為UIScrollViewContentInsetAdjustmentNever 的時候拥诡,adjustContentInset 值不受 SafeAreaInset 值的影響。