Xcode9 iOS11適配 iPhoneX適配 heightForHeaderInSection、contentInset失效解決 contentInsetAdjustmentBehavior詳解
1.iPhoneX基本屬性
啟動圖尺寸:1125px × 2436px(即 375pt × 812pt @3x))
iphoneX 螢幕高:812.0個點
導航欄高度+狀態列高度:88.0個點(導航欄高度仍是44個點,狀態列高度增高為44個點,所以劉海的高度並不是狀態列的高度。狀態列和導航欄平分了頭部總的高度)
tabbar高度:83.0個點(原是固定49個點,增高了34個點。所以)
2.MJRefresh錯位等 使用UIScrollview的控制元件的頁面造成的頁面錯位
iOS11廢棄了automaticallyAdjustsScrollViewInsets屬性,需要使用scrollview的contentInsetAdjustmentBehavior屬性。
- if (@available(iOS 11.0, *)) {
- self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
- } else {
- // Fallback on earlier versions
- }
3.替換寫死的狀態列高度20 導航欄44 和64。安全起見替換寫死的tabbar高度49
[objc] view plain- - (CGFloat)tabbarHeight{
- returnself.tabBarController.tabBar.frame.size.height;
- }
- - (CGFloat)navigationBarHeight{
- returnself.navigationController.navigationBar.frame.size.height;
- }
- - (CGFloat)naviBarAndStatusBarHeight{
-
CGFloat height = self.navigationController
- return height;
- }
4.UITableView中的UITableViewStyleGrouped型別設定heightForHeaderInSection失效
在iOS11上,原來使用UITableViewStyleGrouped設定的sectionheader高度可能失效。本人發現兩種解決辦法
方法一:.在iOS11上tableview的style使用UITableViewStylePlain。
- UITableViewStyle style = UITableViewStyleGrouped;
- if (@available(iOS 11.0,*)) {
- style = UITableViewStylePlain;
- }
- self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) style:style];
- - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
- return yourHeight;
- }
- //注意,設定heightForHeaderInSection的同時也要實現這個代理。 如果不實現這個代理,仍然會出現間隙不均的情況。
- - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
- UIView *header = [[UIView alloc] init];
- header.frame = CGRectMake(0, 0, SCREEN_WIDTH, yourHeight);
- return header;
- }
方法二。所有系統下都使用UITableViewStyleGrouped,然後同時實現以下四個代理方法(在iOS11下,對應的sectionHeaderHeight和sectionHeaderView要成對存在,之前只設置sectionHeaderHeight也可以,所以規範起見:統一成雙入對)
[objc] view plain copy print?- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
- return1;
- }
- - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
- return CountHeight(30);
- }
- - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
- UIView *header = [[UIView alloc] init];
- header.frame = CGRectMake(0, 0, SCREEN_WIDTH, CountHeight(30));
- header.backgroundColor = SHBackgroundColor;
- return header;
- }
- - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
- return0.01;//注意這裡!如果你不需要footerView,這裡不能返回0,否則間距還是有問題
- }
- - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
- return [[UIView alloc] initWithFrame:CGRectZero];
- }
5.contentInset失效。iOS11下引入了safeArea的概念。需要注意這幾個屬性:
[objc] view plain copy print?- 1.UIScrollView的屬性contentInsetAdjustmentBehavior
- 2.UIScrollView的只讀屬性adjustedContentInset
- 3.UIView的只讀屬性safeAreaInsets
iOS11下當你沒有設定contentInsetAdjustmentBehavior時,系統會自動為你將試圖新增到安全區域。
如下圖所示區域
所以,此時你如果仍然設定了contentInset,比如下面的程式碼
[objc] view plain copy print?- self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 49, 0);
解決辦法仍然是兩個:
方法一:
- if (@available(iOS 11.0, *)) {
- self.tableView.contentInset = UIEdgeInsetsMake(headerH, 0, 0, 0);
- }else{//11系統以下,如果需要還是要加的
- self.tableView.contentInset = UIEdgeInsetsMake(headerH, 0, 49, 0);
- }
方法二:
[objc] view plain copy print?- if (@available(iOS 11.0, *)) {
- self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
- }else{
- }
- self.contentInset = UIEdgeInsetsMake(headerH, 0, 49, 0);
6.程式碼塊呼叫失效
Xcode9中原來設定的程式碼塊可能會失效。這個問題比較蛋疼。你去多開啟幾個 多點一下edit,多換一下completion scopes可能就恢復了。
7.contentInsetAdjustmentBehavior詳解
以下引自騰訊bugly博文。(簡單地說就是UIScrollViewContentInsetAdjustmentNever相當於以前的automaticallyAdjustsScrollViewInsets=NO,此時你可遮蔽系統自動調整,佈局由你自己支配。其他三個屬性基本是系統幫你將檢視新增到safeArea裡面)
/* Configure the behavior of adjustedContentInset.
Default is UIScrollViewContentInsetAdjustmentAutomatic.
*/@property(nonatomic) UIScrollViewContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior
adjustContentInset表示contentView.frame.origin偏移了scrollview.frame.origin多少;是系統計算得來的,計算方式由contentInsetAdjustmentBehavior決定。有以下幾種計算方式:
1.UIScrollViewContentInsetAdjustmentAutomatic:如果scrollview在一個automaticallyAdjustsScrollViewContentInset = YES的controller上,並且這個Controller包含在一個navigation controller中,這種情況下會設定在top & bottom上 adjustedContentInset = safeAreaInset + contentInset不管是否滾動。其他情況下與UIScrollViewContentInsetAdjustmentScrollableAxes相同
2.UIScrollViewContentInsetAdjustmentScrollableAxes: 在可滾動方向上adjustedContentInset = safeAreaInset + contentInset,在不可滾動方向上adjustedContentInset = contentInset;依賴於scrollEnabled和alwaysBounceHorizontal / vertical = YES,scrollEnabled預設為yes,所以大多數情況下,計算方式還是adjustedContentInset = safeAreaInset + contentInset
3.UIScrollViewContentInsetAdjustmentNever: adjustedContentInset = contentInset
4.UIScrollViewContentInsetAdjustmentAlways: adjustedContentInset = safeAreaInset + contentInset
當contentInsetAdjustmentBehavior設定為UIScrollViewContentInsetAdjustmentNever的時候,adjustContentInset值不受SafeAreaInset值的影響。