iPhoneX(劉海屏)适配
在 iOS11的時候,蘋果破天荒釋出了一款新螢幕樣式的手機,俗稱劉海屏。世人皆道醜,而後紛紛買之。自此,iOS 開發者們也走向了 iPhoneX系列的适配之旅。
差別
狀态欄,導航欄的改變和底部 Home Indicator的新增 。
普通螢幕 | iPhoneX(劉海屏)系列 | |
---|---|---|
狀态欄高度 | 20 | 44 |
導航欄高度 | 64 | 88 |
tabBar | 49 | 83(其中有34Home Indicator互動區) |
導航欄實際内容展示高度還是44,隻是狀态欄變高。
使用系統原生的導航欄、tabbar系統會自動适配。自定義的都需要手動适配X。比如隐藏了導航欄,使用自定義View代替導航欄的時候,你就需要手動适配(打碼判斷或者參考 SafeArea添加限制)。
iOS 11也引入了安全區域 SafeArea 的概念,以便我們适配和布局參考。
底層View添加限制的時候減少以superView為參考,使用Safe area為限制布局依據,這樣就不用關注是否為劉海屏。
除了這些,還有鍵盤高度的增加等。
判斷 iPhoneX 系列
有部分小夥伴是通過擷取螢幕寬高各版本裝置尺寸來判斷,但是這樣的弊端是,每增加一次裝置都有可能需要添加,非常不推薦。而是應該用 keyWindow 的 SafeArea.bottom來判斷。
Swift
extension UIDevice {
/// 是否為 IphoneX (劉海屏)系列
static var isIphoneXSeries: Bool {
var keyWindow = UIApplication.shared.keyWindow
if #available(iOS 13, *), keyWindow == nil {
keyWindow = UIApplication.shared.windows.first
}
if #available(iOS 11.0, *), UIDevice().userInterfaceIdiom == .phone {
if let key = keyWindow, key.safeAreaInsets.bottom > 0 { // 不能判斷 top(普通螢幕為20, 劉海屏為44),而且還要考慮螢幕旋轉問題。
return true
}
}
return false
}
}
Objective-C
宏定義
#define kIS_iPhoneX_Series ({BOOL isPhoneX = NO;\
if (@available(iOS 13.0, *)) {\
isPhoneX = [UIApplication sharedApplication].windows.firstObject.safeAreaInsets.bottom > 0.0;\
}\
else if (@available(iOS 11.0, *)) {\
isPhoneX = [[UIApplication sharedApplication] delegate].window.safeAreaInsets.bottom > 0.0;\
}\
(isPhoneX);})
其他
Objective-C
相關宏定義
#define kNavBar_Content_Height 44.0f
#define kStatusBar_Height (kIS_iPhoneX_Series==YES)?44.0f: 20.0f
#define kNavBar_Height (kIS_iPhoneX_Series==YES)?88.0f: 64.0f
#define kTabBar_Height (kIS_iPhoneX_Series==YES)?83.0f: 49.0f
Home Indicator 的影藏
針對某些界面,也許我們希望全界面顯示,影藏Inducator
這時候需要重寫ViewController中的如下方法:
// 重寫 控制home indicator的影藏
// 沒有互動兩秒後影藏
-(BOOL)prefersHomeIndicatorAutoHidden{
return YES;
}
Xib适配iPhoneX(相容 iOS11 之前版本)
iOS11版本以上
如果是基于iOS11适配X,你隻需要将限制基準參考Safe Area,就可以解決大部分導航欄和底部欄的适配。
iOS11版本以前
你就需要以SuperView為基準的輔助限制,否則還是會導緻被狀态欄擋住的問題。
綜合解決:
- 添加兩條限制
- Safe Area為基準的限制 優先級 小于 以Super View的。
- 将SuperView為基準的限制關系設定為大于等于【如下圖】。
添加一個UIView作為自定義導航欄。

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-vWmNTRY4-1604631069553)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
同樣的方法也可以适配底部導航欄或視圖。
适配效果圖
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-PI6xaoQz-1604631069554)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
Storyboard裡面隻需要添加以SafeArea為基礎的限制即可。
參考:Safe area layout guides in xib files - iOS 10 --stackOverflow
iOS 11 safe area layout guide backwards compatibility --stackOverflow
擴充:準确擷取iPhone裝置型号
詳細推薦參考:适配iOS11與iPhoneX