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属性。

[objc]  view plain  copy
 print ?
  1.      if (@available(iOS 11.0, *)) {  
  2.         self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;  
  3.     } else {  
  4.         // Fallback on earlier versions  
  5.     }  

3.替换写死的状态栏高度20 导航栏44  和64。安全起见替换写死的tabbar高度49

[objc]  view plain  copy
 print ?
  1. - (CGFloat)tabbarHeight{  
  2.     return self.tabBarController.tabBar.frame.size.height;  
  3. }  
  4.   
  5. - (CGFloat)navigationBarHeight{  
  6.     return self.navigationController.navigationBar.frame.size.height;  
  7. }  
  8.   
  9. - (CGFloat)naviBarAndStatusBarHeight{  
  10.     CGFloat height = self.navigationController.navigationBar.frame.size.height + [UIApplication sharedApplication].statusBarFrame.size.height;  
  11.     return height;  
  12. }  


4.UITableView中的UITableViewStyleGrouped类型设置heightForHeaderInSection失效

在iOS11上,原来使用UITableViewStyleGrouped设置的sectionheader高度可能失效。本人发现两种解决办法

方法一:.在iOS11上tableview的style使用UITableViewStylePlain。

[objc]  view plain  copy
 print ?
  1. UITableViewStyle style = UITableViewStyleGrouped;  
  2.   if (@available(iOS 11.0,*)) {  
  3.       style = UITableViewStylePlain;  
  4.   }  
  5.   self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(00, SCREEN_WIDTH, SCREEN_HEIGHT) style:style];  
然后在代理中照常设置就好了

[objc]  view plain  copy
 print ?
  1. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{  
  2.     return yourHeight;  
  3. }  
  4.   
  5. //注意,设置heightForHeaderInSection的同时也要实现这个代理。 如果不实现这个代理,仍然会出现间隙不均的情况。  
  6. - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{  
  7.     UIView *header = [[UIView alloc] init];  
  8.     header.frame = CGRectMake(00, SCREEN_WIDTH, yourHeight);  
  9.     return header;  
  10. }  

方法二。所有系统下都使用UITableViewStyleGrouped,然后同时实现以下四个代理方法(在iOS11下,对应的sectionHeaderHeight和sectionHeaderView要成对存在,之前只设置sectionHeaderHeight也可以,所以规范起见:统一成双入对)

[objc]  view plain  copy
 print ?
  1. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{  
  2.     return 1;  
  3. }  
  4. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{  
  5.     return CountHeight(30);  
  6. }  
  7. - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{  
  8.     UIView *header = [[UIView alloc] init];  
  9.     header.frame = CGRectMake(00, SCREEN_WIDTH, CountHeight(30));  
  10.     header.backgroundColor = SHBackgroundColor;  
  11.     return header;  
  12. }  
  13. - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{  
  14.     return 0.01;//注意这里!如果你不需要footerView,这里不能返回0,否则间距还是有问题  
  15. }  
  16. - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{  
  17.     return [[UIView alloc] initWithFrame:CGRectZero];  
  18. }  



5.contentInset失效。iOS11下引入了safeArea的概念。需要注意这几个属性:

[objc]  view plain  copy
 print ?
  1. 1.UIScrollView的属性contentInsetAdjustmentBehavior  
  2. 2.UIScrollView的只读属性adjustedContentInset  
  3. 3.UIView的只读属性safeAreaInsets  

iOS11下当你没有设置contentInsetAdjustmentBehavior时,系统会自动为你将试图添加到安全区域。

如下图所示区域


所以,此时你如果仍然设置了contentInset,比如下面的代码

[objc]  view plain  copy
 print ?
  1. self.tableView.contentInset = UIEdgeInsetsMake(00490);  
就会出现下方多了49个点。

解决办法仍然是两个:

方法一:

[objc]  view plain  copy
 print ?
  1. if (@available(iOS 11.0, *)) {  
  2.     self.tableView.contentInset = UIEdgeInsetsMake(headerH, 000);  
  3. }else{//11系统以下,如果需要还是要加的  
  4.     self.tableView.contentInset = UIEdgeInsetsMake(headerH, 0490);  
  5. }  

方法二:

[objc]  view plain  copy
 print ?
  1. if (@available(iOS 11.0, *)) {  
  2.      self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;  
  3.  }else{  
  4.  }  
  5.  self.contentInset = UIEdgeInsetsMake(headerH, 0490);  

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值的影响。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值