1. 程式人生 > >iOS開發之適配iOS11&iPhoneX的一些坑

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(
00, 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