前言
北京時間今天凌晨1點,蘋果再一次讓全世界沸騰。iPhone X 帶給我們的最大改變:全屏 Super Retina螢幕。它提供了更多的內容顯示空間,同時也營造了更加深入的沉浸感。作為 iOS 開發者,在為強大的 Face ID 和全面屏欣喜的同時,我更擔憂“齊劉海”的適配! 下面結合官方的人機互動指南,來了解下如何設計 App 才能在iPhone X 和其他所有 iOS 裝置上都看起來很棒。
理論部分
螢幕尺寸
在豎屏下,iPhone X 上的顯示的寬度與 iPhone 6,iPhone 7和 iPhone 8的4.7英寸螢幕的寬度保持一致。然而,iPhone X 比4.7英寸螢幕高了145個點,這導致增加了大約20%的垂直高度內容。
大家在為設計師悲傷的同時也不要忘記新增啟動圖(LaunchImage or LaunchScreen.storyboard)呦~
安全區
在 iPhone X 佈局中,最關鍵的是:必須確保佈局填滿螢幕,同時又不會被裝置的圓角,感測器外殼或用於訪問主螢幕的指示燈所遮蓋,蘋果為稱此區域為“安全區”。
可喜的是,大多數標準的系統提供的UI元素和控制元件(如 navigation bars,tables 和 collections)都已經為新外形做了很好的適配。 背景已經延伸到顯示器的邊緣,並且UI元件被很恰當地插入和定位在安全區域。 因此,對於具有自定義佈局的 App,支援iPhone X 也應該比較容易,特別是如果使用了 AutoLayout 並遵守安全區域(safe area)和邊距佈局(margin layout)指南。這些在上文都已經有過較詳細的闡述。 下面說幾點需要特別注意的:
-
在 iPhone X 上預覽 App: 在拿到新機之前,也可以先使用 Simulator 來預覽和檢查下佈局問題。 但是一些依賴硬體的功能,如影像效果和互動體驗,最好還是在真機上預覽。
-
始終保持全屏體驗: 確保背景延伸到顯示區域的邊緣,以及垂直可滾動的佈局(如 tables 和 collections)一直延續到底部。
-
防止邊緣內容被裁剪: 一般來說,內容應該是居中對稱的,這樣它在任何方向看起來都會很棒,不會被邊角角或裝置外殼夾住,或被主螢幕的指示器遮擋。 為了獲得最佳效果,請使用標準的系統介面元素和 AutoLayout 構建介面。 所有 App 都應遵循 UIKit 定義的安全區域和佈局邊距,因為這些區域可以根據裝置和上下文進行適當的填充。 安全區域還可以防止內容覆蓋status bar, navigation bar, toolbar, 以及 tab bar.
-
注意 status bar 的高度: status bar 在iPhone X 上比在其他 iPhone上更高。 如果假定你固定 status bar 的高度用於將內容定位在 status bar 的下方,那麼現在必須更新你的的 App,才能根據使用者的裝置動態定位內容。 特別需要注意,當後臺任務(如錄音和位置跟蹤)處於活動狀態時,iPhone X上的狀態列不會改變高度。
-
重新考慮隱藏 status bar: iPhone X 較之顯示高度為4.7“iPhone 的螢幕提供了更多的內容垂直空間,status bar 佔據的只是擴充套件出來的螢幕區域。況且 status bar 更直觀的顯示使用者有用的資訊,如果非要隱藏狀態列,那最好用與這些資訊同等重要的內容替代。
-
注意長寬比差異: iPhone X 具有不同於4.7“iPhone 的長寬比。因此,全屏4.7英寸iPhone 圖形在iPhone X 上全屏顯示時出現裁剪或 letterboxing 。同樣,全屏iPhone X 圖形全屏顯示在4.7“iPhone 上時也會被裁剪或 pillarboxing ,因此要確保重要的視覺內容適配這兩種尺寸。
- 避免互動式控制元件出現在螢幕底部和角落: iPhone X 提供了螢幕底部的滑動手勢來訪問主螢幕和應用程式切換器的新互動方式,這些手勢可能會取消在此區域中實現的自定義手勢。 況且螢幕的兩個角落過多複雜的互動也不是最佳體驗的良好實踐。
-
不要遮擋或者特別修飾顯示特性來引起使用者注意: 請勿嘗試隱藏裝置的圓角、感測器外殼,或者通過在螢幕頂部和底部放置控制元件來訪問主螢幕的引導。也要特別注意不要試圖使用像括號,邊框或各種符號等視覺修飾這些特殊區域。
-
為了輕鬆訪問主螢幕允許自動隱藏指示器: 當開啟自動隱藏時,如果使用者離開螢幕幾秒鐘,指示器將消失。 當使用者再次觸控螢幕時,它會重新出現。 這種行為應該只能用於提升觀看體驗,如播放視訊或照片幻燈片。
色彩
iPhone X 的顯示器支援 P3 色彩空間,它可以產生比 sRGB 更豐富,更飽和的顏色。
可以使用 wide color 來增強視覺體驗。 它可以讓照片和視訊更加逼真生動。
更多內容可以參考官網Color management(https://developer.apple.com/ios/human-interface-guidelines/visual-design/color/#color-management)
手勢
想必大家都在釋出會上看到了,iPhone X 上的螢幕可以使用螢幕邊緣手勢來訪問主螢幕,應用程式切換器,通知中心和控制中心。適應這個新變化的同時,對於開發者要特別注意: 避免干擾系統範圍的螢幕邊緣手勢:使用者依賴這些手勢在每個 App 中操作,所以在極少數情況下,比如遊戲這種強調沉浸式體驗的 App 可能需要自定義的螢幕邊緣手勢,優先順序高於系統的手勢。 這種行為(稱為邊緣保護)應該謹慎使用,因為它使得使用者難以訪問系統級的操作。
更多內容參考官網Gestures
(https://developer.apple.com/ios/human-interface-guidelines/user-interaction/gestures/)
補充的注意事項
- 認證方法準確:iPhone X 支援 Face ID進行身份驗證。 如果你的 App 整合了 Apple Pay 或其他系統身份驗證功能,請務必注意不要在 iPhone X 上引用 Touch ID。同樣地,也請確保不要在支援Touch ID 的裝置上引用 Face ID。
更詳細的內容請參考Authentication(https://developer.apple.com/ios/human-interface-guidelines/user-interaction/authentication/)
-
不要重複增加系統提供的鍵盤功能:在 iPhone X上,即使使用自定義鍵盤,Emoji / Globe 按鈕和 Dictation 按鈕也自動顯示在鍵盤的下方。 你的 App 不能影響這些按鈕,因此避免在鍵盤中重複增加這些按鈕造成混亂。
-
由於 iPhone X的螢幕比例發生變化,對於長期靠“等比縮放”完成適配的H5活動頁而言也有不小的影響,需要對頁面結構進行適當微調。
更詳細內容請參閱Custom-keyboards(https://developer.apple.com/ios/human-interface-guidelines/extensions/custom-keyboards/)
判斷 iPhone X 機型 (Swift)
如何判斷當前的裝置是 iPhone X 呢?有好幾種辦法,可以考慮取得「iPhone 10,1」這樣的 Module Name 來判斷,也可以用螢幕解析度的形式來判斷。我覺得要用螢幕解析度的方式來做,因為這是目前為止最簡單也最不容易出錯的。因為 iPhone X 只有一種解析度,那就是 812pt x 375pt (@3x),且沒有任何其他裝置用了一樣的解析度,特別是高度。
於是寫了一個基於 UIDevice 的擴充套件(或者其他任意方法也行):
extension UIDevice {
public func isX() -> Bool {
if UIScreen.main.bounds.height == 812 {
return true
}
return false
}
}
複製程式碼
在程式碼中,就可以用 UIDevice.current.isX() 來判斷是不是跑在 iPhone X 機型上,然後做一些或不做一些特殊的 Hack 了。
當然如果你習慣用三方庫,也可以嘗試“DeviceKit”
let device = Device()
print(device) // prints, for example, "iPhone X"
if device == .iPhoneX {
// Do something
} else {
// Do something else
}
複製程式碼
程式碼適配部分
當我們能夠判斷出裝置型號就可以配合系統版本進行適配了
1.適配 UITableView 元件
if (@available(iOS 11.0, *)) {
self.contentInsetAdjustmentBehavior = .never
self.estimatedRowHeight = 0
self.estimatedSectionHeaderHeight = 0
self.estimatedSectionFooterHeight = 0
} else {
// Fallback on earlier versions
}
複製程式碼
2.適配 UIScrollView 元件
if (@available(iOS 11.0, *)) {
scrollView?.contentInsetAdjustmentBehavior = .never
} else {
// Fallback on earlier versions
}
複製程式碼
3.UITableView中的sectionHeader或者Footer顯示不正常
還有的發現某些介面tableView的sectionHeader、sectionFooter高度與設定不符的問題,在iOS11中如果不實現-tableView: viewForHeaderInSection:和-tableView: viewForFooterInSection:,則-tableView: heightForHeaderInSection:和- tableView: heightForFooterInSection:不會被呼叫,導致它們都變成了預設高度,這是因為tableView在iOS11預設使用Self-Sizing,tableView的estimatedRowHeight、estimatedSectionHeaderHeight、estimatedSectionFooterHeight三個高度估算屬性由預設的0變成了UITableViewAutomaticDimension,解決辦法簡單粗暴,就是實現對應方法或把這三個屬性設為0。
if #available(iOS 11.0, *) {
tableView.estimatedRowHeight = 0;
tableView.estimatedSectionHeaderHeight = 0;
tableView.estimatedSectionFooterHeight = 0;
} else {
automaticallyAdjustsScrollViewInsets = false;
};
複製程式碼
4.適配網頁載入不全下面有白邊
if #available(iOS 11.0, *) {
webView.scrollView.contentInsetAdjustmentBehavior = .never
} else {
};
複製程式碼
5.適配iPhoneX不能鋪滿屏的問題
<1>給Brand Assets新增一張1125*2436大小的圖片
開啟Assets.xcassets資料夾,找到Brand Assets
右鍵Show in Finder
新增一張1125*2436大小的圖片
<2>修改Contents.json檔案,新增如下內容
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "2436h",
"filename" : "1125_2436.png”,
"minimum-system-version" : "11.0",
"orientation" : "portrait",
"scale" : "3x"
}
複製程式碼
<3>使用 LaunchScreen.storyboard 設定啟動圖
使用 LaunchScreen.storyboard 檔案將簡單檢視約束定位,實現各種尺寸的自適應。
6.適配iPhoneX
//適配iPhoneX
let LL_iPhoneX = (kScreenW == Double(375.0) && kScreenH == Double(812.0) ?true:false)
let kNavibarH = LL_iPhoneX ? Double(88.0) : Double(64.0)
let kTabbarH = LL_iPhoneX ? Double(49.0+34.0) : Double(49.0)
let kStatusbarH = LL_iPhoneX ? Double(44.0) : Double(20.0)
複製程式碼
7.Xcode9 打包注意事項
Xcode9 打包版本只能是8.2及以下版本,或者9.0及更高版本
Xcode9 不支援8.3和8.4版本
Xcode9 新打包要在構建版本的時候加入1024*1024 AppSore icon
Xcode9 沿用了之前的分包設計,可以配置打出多種裝置的包檔案,使用者安裝時根據裝置不同分別安裝不同的API包,減小安裝包大小。
8.iOS 11 相簿許可權變更
iOS11以前:
NSPhotoLibraryUsageDescription:訪問相簿和儲存照片到相簿(讀寫),會出現使用者授權。
iOS11之後:
NSPhotoLibraryUsageDescription:無需新增。預設開啟訪問相簿許可權(讀),無需使用者授權。
NSPhotoLibraryAddUsageDescription: 新增內容到相簿。(寫),會出現使用者授權。