相信大家已经被iPhoneX的刘海洗脑了,除了吐槽,留给我们的还有比较麻烦的适配工作。下面针对在整理过程中发现的适配注意点进行简单分享下。
适配:
1.iPhone X 尺寸
2.iPhone X 上下显示黑条问题
3.导航栏的适配
4.iOS11新增版本判断API
5.UITableView相关适配
6.安全区域的问题
7.上传版本提示警告的问题
8.iOS 11 新增的隐私设置
一. iPhone X 尺寸
开发尺寸是375 * 812 pt
二. iPhone X 上下显示黑条问题
运行Xcode9.0的iPhoneX模拟器, APP在iPhoneX屏幕没填充满,上下有黑色区域, 未适配前:
这是因为app之前未用LaunchScreen.Storyboard作为启动页面,可以使用LaunchScreen来当做入场页面,这样APP才会自动适配为iPhoneX的大小。我的项目中是用Assets中的LaunchImage, 这样就可以修改Assets中的LaunchImage,添加iPhoneX的Launch图(1125*2436), 记得勾选如下图所示。
这个时候看下效果图:
三. 导航栏的适配
3.1 导航栏新增了一种大标题样式
默认设置是不开启,所以不需要修改。
3.2 高度适配
iOS 11以前,导航栏的高度是64,其中状态栏statusBar的高度是20,底部tabbar的高度是49。
iOS 11之后,iPhoneX的导航栏的高度是88,其中状态栏的statusBar的高度变成了44, 底部的tabbar变成了83。
iPhoneX的底部增加了虚拟Home区,由于安全区域的原因默认tabBar的高度由49变为83,增高了34,所以自定义的底部TabBar也需要需改其适配方案。
先来考虑关于navi 在 iPhone X 上是88的问题.
目前没发现有iPhoneX的机型判断API,建议使用size来做代替判断。
// 导航条高度
#define UI_navBar_Height ((UI_View_Height == 812) ? 88.0 : 64.0)
如果要在 navi 上添加渐变的背景图, 则要控制 navi 的高
- (UIImageView *)alphaView {
if (!_alphaView) {
CGRect frame = self.navigationBar.frame;
CGFloat h = UI_navBar_Height; // is 812 ? 88 : 64
UIImageView *alphaView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, h)];
alphaView.image = [UIImage imageNamed:@"bg_gradient"];
[self.navigationBar.subviews.firstObject insertSubview: alphaView atIndex:0];
_alphaView = alphaView;
}
return _alphaView;
}
自定义的底部TabBar也需要改其适配方案, 则考虑适配 iPhone X
// 底部tabbar高度
#define UI_tabBar_Height ((UI_View_Height == 812) ? 83.0 : 49.0)
3.3 titleView支持autolayout
这要求titleView必须是能够自撑开的或实现了- intrinsicContentSize,
这里以UISearchBar为例, 我是外层添加了titleView容器. 高度控制着35的.
// 设置titleView
UIView *titleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 35)];//allocate titleView
[titleView setBackgroundColor:[UIColor clearColor]];
// 搜索工具条
UISearchBar *searchBar = [[UISearchBar alloc] init];
searchBar.placeholder = @"|搜索会员";
searchBar.frame = CGRectMake(0, 0, titleView.width, 30);
searchBar.center = titleView.center;
searchBar.delegate = self;
[titleView addSubview:searchBar];
[self.navigationItem.titleView sizeToFit];
self.navigationItem.titleView = titleView;
修改后, 发现UISearchBar圆角变形了,
这个时候我们可以添加设置圆角的, 效果如下:
searchBar.layer.cornerRadius = 10;
searchBar.layer.masksToBounds = YES;
- 如果是自定义titleview, 只需要在你自定义的titleview对应的 View中实现- intrinsicContentSize方法;
- (CGSize)intrinsicContentSize {
return UILayoutFittingExpandedSize;
}
- 如果你的项目是自定义的navigationBar,那么在iOS11上运行就可能出现布局错乱,解决办法是重写UINavigationBar的 layoutSubviews方法,调整布局,代码如下:
- (void)layoutSubviews {
[super layoutSubviews];
//注意导航栏及状态栏高度适配
self.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), naviBarHeight);
for (UIView *view in self.subviews) {
if([NSStringFromClass([view class]) containsString:@"Background"]) {
view.frame = self.bounds;
}
else if ([NSStringFromClass([view class]) containsString:@"ContentView"]) {
CGRect frame = view.frame;
frame.origin.y = statusBarHeight;
frame.size.height = self.bounds.size.height - frame.origin.y;
view.frame = frame;
}
}
}
四. iOS11新增版本判断API
iOS11版本现在有了简单的API,OC也开始支持swfit的@available
语法,就可以不用再手写判断iOS版本了。
if (@available(iOS 11.0, *)) {
// 版本适配
}
// 或者
#ifdef __IPHONE_11_0
#endif
五. UITableView相关适配
5.1 tableview的组头和组尾高度问题
iOS11开始UITableView开启了自动估算行高,estimatedRowHeight
estimatedSectionHeaderHeight
estimatedSectionFooterHeight
三个高度估算属性由默认的0变成了UITableViewAutomaticDimension,把这三属性设置成0.01即可.
解决iOS11刷新tableview会出现漂移的现象, 添加以下代码关闭估算行高:
self.tableView.estimatedRowHeight = 0.01;
self.tableView.estimatedSectionHeaderHeight = 0.01;
self.tableView.estimatedSectionFooterHeight = 0.01;
在heightForHeaderInSection和viewForHeaderInSection应该一起使用,不然tableView顶部滑动的时候会有空白。
在heightForFooterInSection和viewForFooterInSection也应该一起使用, 如果仅仅 设置高度, 则tableView底部View根本没有展现。
5.2 Header/Footer返回size不能再为负值
在适配过程中发现UITableView会在Header/Footer返回size为负值的情况下会(之前遗漏的bug)崩溃,这块建议都修改为0.01,而iOS11之前的版本不会。
六.安全区域的问题
- iOS 11之前, automaticallyAdjustsScrollViewInsets经常被设置成NO,由开发者去控制处理留白和坐标问题, 但是11+
automaticallyAdjustsScrollViewInsets = NO
这句代码失效。 - iOS 11后,把这个automaticallyAdjustsScrollViewInsets废弃,新增了
contentInsetAdjustmentBehavior
,这个属性是个枚举类型值,我们只需要把其设置成never就行了
解决tableView偏移88的问题, 我们可以对对 tableView 进行如下设置:
if (@available(iOS 11.0, *)) {
self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
self.automaticallyAdjustsScrollViewInsets = NO;
}
七.Marketing Icon上传版本提示警告的问题
更新适配版本时 iPhone X 的启动图适配加上了, 千万别忘了也要传 Icon. 否则就会有上传版本时会有提示警告滴~
9月份上传的时候, 没有1024*1024的营销图标只是有警告, 现在上传的时候也是有警告的, 只不过现在提交审核的时候直接不能提交审核!
今天折腾一天,无论怎么更换这张图片(1024x1024的 png图)都不行, 最后换了一种上传方式Archive在线打包
就好了,很尴尬~
八.iOS 11 新增的隐私设置
今天调试项目时有一个生成长图并保存到本地的功能,一点击保存相册就发现闪退了。发现 Xcode 报以下错误:
This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryAddUsageDescription key with a string value explaining to the user how the app uses this data.
问题跟 iOS 10 保存图片、调用相机一样, Info.plist 里面要涉及隐私数据时要添加提示语。
打开 Info.plist,点击 + 号,在 Key 中输入:Privacy - Photo Library Additions Usage Description,Type 选择 String,Value 中输入你的提示语。
这是 iOS 11 新出的一条隐私规则,说明如下:
iOS11下,苹果对相册的权限key做了调整,原来NSPhotoLibraryUsageDescription,在iOS11之后,改成了NSPhotoLibraryAddUsageDescription
iOS 11 新增的隐私设置
iOS 11 中新加的还有一个跟 NFC 设备有关 NFCReaderUsageDescription,不过暂时没接触到。
目前在iOS11/iPhoneX遇到这么多坑,以后遇到会继续分享的。
推荐一篇博客技术文, 有些内容我也是从这大神里学滴: http://fighting300.com/2017/09/14/iOS11-UI-adjust/