iOS開發之適配iOS11&iPhoneX的一些坑
導航欄
導航欄高度的變化
iOS11之前導航欄預設高度為64pt(這裡高度指statusBar + NavigationBar),iOS11之後如果設定了prefersLargeTitles = YES則為96pt,預設情況下還是64pt,但在iPhoneX上由於劉海的出現statusBar由以前的20pt變成了44pt,所以iPhoneX上高度變為88pt,如果專案裡隱藏了導航欄加了自定義按鈕之類的,這裡需要注意適配一下。
導航欄圖層及對titleView佈局的影響
iOS11之前導航欄的title是新增在UINavigationItemView上面,而navigationBarButton則直接新增在UINavigationBar上面,如果設定了titleView,則titleView也是直接新增在UINavigationBar上面。iOS11之後,大概因為largeTitle的原因,檢視層級發生了變化,如果沒有給titleView賦值,則titleView會直接新增在_UINavigationBarContentView上面,如果賦值了titleView,則會把titleView新增在_UITAMICAdaptorView上,而navigationBarButton被加在了_UIButtonBarStackView上,然後他們都被加在了_UINavigationBarContentView上,如圖:
所以如果你的專案是自定義的navigationBar,那麼在iOS11上執行就可能出現佈局錯亂的bug,解決辦法是重寫UINavigationBar的layoutSubviews方法,調整佈局,上程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
- ( void )layoutSubviews {
[ super layoutSubviews];
//注意導航欄及狀態列高度適配
self.frame = CGRectMake( 0 , 0 , CGRectGetWidth(self.frame), naviBarHeight);
for (UIView *view in self.subviews) {
if ([NSStringFromClass([view class ]) containsString:@ "Background" ]) {
view.frame = self.bounds;
}
else if ([NSStringFromClass([view class ]) containsString:@ "ContentView" ]) {
CGRect frame = view.frame; frame.origin.y = statusBarHeight;
frame.size.height = self.bounds.size.height - frame.origin.y;
view.frame = frame;
}
}
}
|
再補充一點,看了簡書App適配iOS11發現titleView支援autolayout,這要求titleView必須是能夠自撐開的或實現了- intrinsicContentSize方法
1 2 3 |
- (CGSize)intrinsicContentSize {
return UILayoutFittingExpandedSize;
}
|
UIScrollView、UITableView、UICollectionView
大家在iOS11裝置上執行出現最多問題應該就是tableview莫名奇妙的偏移20pt或者64pt了。。原因是iOS11棄用了automaticallyAdjustsScrollViewInsets屬性,取而代之的是UIScrollView新增了contentInsetAdjustmentBehavior屬性,這一切的罪魁禍首都是新引入的safeArea