过了好久,今天终于有时间总结一下适配 iPhone X 相关的坑,总的来说有两类坑,一个是导航栏 + 状态栏的高度发生了变化,一个是一些没有实现实现
- tableView: viewForHeaderInSection:
和
- tableView: viewForFooterInSection:
等代理方法的 UITableView 会出错位的问题.
image.png
1. 判断是否 iPhone X:返回 YES 或 NO
1.1 判断:宏
(1)依据屏幕分辨率
三目运算法
多行逻辑判断
//是否iPhoneX YES:iPhoneX屏幕 NO:传统屏幕
#define kIs_iPhoneX([UIScreen instancesRespondToSelector: @selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO)
其中,反斜杠 \ 并不是注释或者其它的无用符号,其实是多行宏换行必须要用的标志.
//是否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)依据屏幕尺寸
1.2 判断:方法
#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)
方法:依据设备型号
2. 灵活返回状态栏 + 导航栏的高度
+ (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;
}
}
需求:灵活得到导航栏 + 状态栏的高度,作为一个子视图 Y 轴的起点.
宏定义
#define kStatusBarAndNavigationBarHeight(kIs_iPhoneX ? 88.f: 64.f)
调用范例
3. 拓展:获得 iOS 系统与 App 版本信息
//自动适配
_segmentedControl.frame = CGRectMake(0, kStatusBarAndNavigationBarHeight, kSCREEN_WIDTH, 55);
获取 iOS 系统版本号:返回字符串
获取 App 版本号:返回字符串
+ (NSString * ) getSystemVersion {
return [[UIDevice currentDevice] systemVersion];
}
4. 适配 iPhone X 的其他问题
+ (NSString * ) getAppVersion {
NSDictionary * infoDic = [[NSBundle mainBundle] infoDictionary];
// 获取App的版本号
NSString * appVersion = [infoDic objectForKey: @"CFBundleShortVersionString"];
return appVersion;
}
适配 iPhone X 和 Xcode 9 的过程中,除了与导航栏相关的问题,还有一个问题经常出现,就是 UITableView 相关的问题.下面两个办法可以解决多数错位的问题.
VC 创建 tableView 属性的时候这样设置
还可以这样设置
self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0;
self.tableView.estimatedSectionFooterHeight = 0;
关于根视图的安全区
//cell自适应高度
self.tableView.rowHeight = UITableViewAutomaticDimension;
//预估行高
self.tableView.estimatedRowHeight = 44.0f;
iOS 新增了个 safeArea,原来的老代码中,规定子视图跟根子视图的关系的代码需要新增一个判断:当 iOS 11 时,需要改为子视图跟根子视图的安全区的关系.这样就不会在 iPhone X 的底部虚拟 home 有任何控件干扰了.
当然,一般除了 tabbar 不能放在这个底部虚拟 home 区,其它的视图 tableView 视图或者网页视图时可以放在底部虚拟 home 区中的.这时候,不需要强调必须把子视图放在 safeArea 之内,原来的老代码也就不用改.
if (@available(iOS 11.0, *)) {
make.edges.equalTo(self.view.safeAreaInsets)
} else {
make.edges.equalTo(self.view)
}
来源: http://www.jianshu.com/p/a4cfe905fb72