iOS11.0&&iPhoneX适配

Xcode build

Posted by hdj on November 13, 2017

前言

iOS 更新了11.0以及iPhone X发布之后,各种蛋疼的适配让人无所适从,在此记录一下 适配当中遇到的坑以及解决方法。

参考1

参考2

准备

  // 判断是否是iPhone X
  #define kDevice_Is_iPhoneX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO)
  
  // 宏定义 获取当前的 状态栏的高度 和导航栏的高度

  #define NAVBAR_HEIGHT ([[UIApplication sharedApplication] statusBarFrame].size.height + self.navigationController.navigationBar.frame.size.height)
  
  // tabbar 高度
  #define TABBAR_HEIGHT (kDevice_Is_iPhoneX? 83.:49.)

1. tabview 适配

实现思路,通过runtime修改初始化方法。

新建UITableView分类: UITableView+Category.h

1. 新增runtime交换函数实现方法

  + (void)exChangeInit{
      static dispatch_once_t onceToken;
      dispatch_once(&onceToken, ^{
          SEL originalSelector = @selector(initWithFrame:style:);
          SEL swizzledSelector = @selector(dj_initWithFrame:style:);
          Class class = [self class];
          Method originalMethod = class_getInstanceMethod(class, originalSelector);
          Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
          BOOL didAddMethod =
          class_addMethod(class,
                          originalSelector,
                          method_getImplementation(swizzledMethod),
                          method_getTypeEncoding(swizzledMethod));
          if (didAddMethod) {
              class_replaceMethod(class,
                                  swizzledSelector,
                                  method_getImplementation(originalMethod),
                                  method_getTypeEncoding(originalMethod));
          } else {
              method_exchangeImplementations(originalMethod, swizzledMethod);
          }
      });
  }

2. 重写load方法:

    + (void)load{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    [UITableView appearance].estimatedRowHeight = 0;
    [UITableView appearance].estimatedSectionHeaderHeight = 0;
    [UITableView appearance].estimatedSectionFooterHeight = 0;
    //iOS11 解决SafeArea的问题,同时能解决pop时上级页面scrollView抖动的问题
        [UITableView exChangeInit];
    });
    
    if (@available(iOS 11, *)) {
    //        [UIScrollView appearance].contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; //iOS11 解决SafeArea的问题,同时能解决pop时上级页面scrollView抖动的问题
    }
    
    }

3. 重写init方法

   - (UITableView *)dj_initWithFrame:(CGRect)frame{
       return [[UITableView alloc]dj_initWithFrame:frame style:UITableViewStylePlain];
   }
   
  - (UITableView *)dj_initWithFrame:(CGRect)frame style:(UITableViewStyle)style{
      CGFloat height = frame.size.height;
      NSLog(@"tableView frame:%@ ",NSStringFromCGRect(frame));
      UITableView *tableView =  [self dj_initWithFrame:frame style:(int)style];
      if(tableView){
          if (@available(iOS 11.0, *)) {
              NSLog(@"new init ios 11");
              tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
             
              if(kDevice_Is_iPhoneX){
                  tableView.frame = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height - 44);
               }
           }
      }
      return self;
  }

搞定.