首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往
21 篇文章
1
iOS开发·第三方数据库处理框架:Realm 基本用法
2
iOS开发·KVC:字典转模型,防止因本地未定义字段(后台的字段与本地字符串名不一致)导致数据转换过程中的奔溃
3
iOS开发·第三方网络下载处理框架:AFNetworking网络下载处理(官方文档翻译篇)
4
iOS开发·NSString字符串的各种基本操作,数值转换及衍生操作
5
iOS开发·NSDate日期基本操作方法
6
iOS开发·必会的算法操作:字符串数组排序+模型对象数组排序
7
iOS开发·UIWindow与视图层级调整技巧(makeKeyWindow,resignKeyWindow,makeKeyAndVisible,keyWindow,windowLevel,UIWind
8
iOS开发·适配iPhone X相关的宏和方法
9
iOS开发·KVO用法,原理与底层实现: runtime模拟实现KVO监听机制(Blcok及Delgate方式)
10
iOS开发·runtime原理与实践: 基本知识篇(类,超类,元类,super_class,isa,对象,方法,SEL,IMP)
11
iOS开发·runtime原理与实践: 关联对象篇(Associated Object)(应用场景:为分类添加“属性”,为UI控件关联事件Block体,为了不重复获得某种数据)
12
iOS开发·runtime+KVC实现多层字典模型转换(多层数据:模型嵌套模型,模型嵌套数组,数组嵌套模型)
13
iOS开发·runtime原理与实践: 方法交换篇(Method Swizzling)(iOS“黑魔法”,埋点统计,禁止UI控件连续点击,防奔溃处理)
14
iOS开发·runtime原理与实践: 消息转发篇(Message Forwarding) (消息机制,方法未实现+API不兼容奔溃,模拟多继承)
15
iOS开发·网络请求方法总结复习(NSURLConnection,NSURLSession,AFNetworking)
16
iOS开发·由SDWebImage引发的知识点聚合与思考(最新呕心沥血之作)
17
iOS开发·RunLoop源码与用法完全解析(输入源,定时源,观察者,线程间通信,端口间通信,NSPort,NSMessagePort,NSMachPort,NSPortMessage)
18
iOS开发·紫色感叹号
19
iOS开发·设置状态栏颜色的小结与误区
20
iOS开发·专职协议声明的头文件
21
iOS开发·状态栏设置技巧2:更新状态栏

iOS开发·适配iPhone X相关的宏和方法

过了好久,今天终于有时间总结一下适配iPhone X相关的坑,总的来说有两类坑,一个是导航栏+状态栏的高度发生了变化,一个是一些没有实现实现-tableView: viewForHeaderInSection:-tableView: viewForFooterInSection:等代理方法的UITableView会出错位的问题。

image.png

1. 判断是否iPhone X:返回YES或NO

1.1 判断:宏
(1)依据屏幕分辨率
  • 三目运算法
代码语言:javascript
复制
//是否iPhoneX YES:iPhoneX屏幕 NO:传统屏幕
#define kIs_iPhoneX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO)
  • 多行逻辑判断
代码语言:javascript
复制
//是否iPhoneX 1:iPhoneX屏幕 0:传统屏幕
#define kIs_iPhoneX_test ({\
int tmp = 0;\
if ([UIScreen instancesRespondToSelector:@selector(currentMode)]) {\
    if (CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size)) {\
        tmp = 1;\
    }else{\
        tmp = 0;\
    }\
}else{\
    tmp = 0;\
}\
tmp;\
})

  • 其中,反斜杠\并不是注释或者其它的无用符号,其实是多行宏换行必须要用的标志。
  • 最后一句tmp;\也是必须的,因为要将经过逻辑判断得到的tmp作为该宏的返回值。
(2)依据屏幕尺寸
代码语言:javascript
复制
#define kIs_iPhoneX (kSCREEN_WIDTH == 375.f && kSCREEN_HEIGHT == 812.f)
#define kSCREEN_WIDTH  ([UIScreen mainScreen].bounds.size.width)
#define kSCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height)
1.2 判断:方法
  • 方法:依据设备型号
代码语言:javascript
复制
+(BOOL)getIs_iPhoneX{
    struct utsname systemInfo;
    uname(&systemInfo);
    NSString *platform = [NSString stringWithCString: systemInfo.machine encoding:NSASCIIStringEncoding];
    
    if([platform isEqualToString:@"iPhone10,3"]||[platform isEqualToString:@"iPhone10,6"]) {
        return YES;
    }else{
        return NO;
    }
}

2. 灵活返回状态栏+导航栏的高度

需求:灵活得到导航栏+状态栏的高度,作为一个子视图Y轴的起点。

  • 宏定义
代码语言:javascript
复制
#define kStatusBarAndNavigationBarHeight (kIs_iPhoneX ? 88.f : 64.f)
  • 调用范例
代码语言:javascript
复制
//自动适配
_segmentedControl.frame = CGRectMake(0, kStatusBarAndNavigationBarHeight, kSCREEN_WIDTH, 55);

3. 拓展:获得iOS系统与App版本信息

  • 获取iOS系统版本号:返回字符串
代码语言:javascript
复制
+ (NSString *)getSystemVersion{
    return [[UIDevice currentDevice] systemVersion];
}
  • 获取App版本号:返回字符串
代码语言:javascript
复制
+ (NSString *)getAppVersion{
    NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary];
    // 获取App的版本号
    NSString *appVersion = [infoDic objectForKey:@"CFBundleShortVersionString"];
    return appVersion;
}

4. 适配iPhone X的其他问题

适配iPhone X和Xcode 9的过程中,除了与导航栏相关的问题,还有一个问题经常出现,就是UITableView相关的问题。下面两个办法可以解决多数错位的问题。

  • VC创建tableView属性的时候这样设置
代码语言:javascript
复制
self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0;
self.tableView.estimatedSectionFooterHeight = 0;
  • 还可以这样设置
代码语言:javascript
复制
//cell自适应高度
self.tableView.rowHeight = UITableViewAutomaticDimension;
//预估行高
self.tableView.estimatedRowHeight = 44.0f; 
  • 关于根视图的安全区

iOS新增了个safeArea,原来的老代码中,规定子视图跟根子视图的关系的代码需要新增一个判断:当iOS 11时,需要改为子视图跟根子视图的安全区的关系。这样就不会在iPhone X的底部虚拟home有任何控件干扰了。

代码语言:javascript
复制
if (@available(iOS 11.0, *)) {
    make.edges.equalTo(self.view.safeAreaInsets)
} else {
    make.edges.equalTo(self.view)
}

当然,一般除了tabbar不能放在这个底部虚拟home区,其它的视图tableView视图或者网页视图时可以放在底部虚拟home区中的。这时候,不需要强调必须把子视图放在safeArea之内,原来的老代码也就不用改。

下一篇
举报
领券