终于我还是适配 iOS11 和 iPhone X 了。其实已经适配好几天了,今天发了版本,把这次在适配中遇到的问题,还是总结下,以备以后的不时之需。如果有做的不好的地方,还请各路大大多多指点。
刚开始什么都没动,在 X 上跑,大致跑了下,感觉没啥问题,高高兴兴去群里说我的项目在X上跑一点问题都没,不需要适配。等我静下心来,欣赏iPhone X的美时(安安静静在模拟器上跑项目),发现事实并不是那么美好。主要问题有以下几个:
一、push 和 pop时,页面偏移
在有UIScrollView或UIScrollView子类(如tableView)的控制器中,push到第二个几面和pop回去,scrollView都会往下偏移。来上图
可能已经看到了,有一个向上的偏移效果,看着可别扭。不用担心,解决办法是有滴,不过整个工程那么多UIScrollView及它的子类,每个都去修改是非常捣蛋的,所以我们可以直接在AppDelegate中用UISCrollView的UIAppearance修改,代码如下:
// AppDelegate 进行全局设置 不然iOS 11 push时界面会有个下滑的效果,pop回去会有个上划的效果
if (@available(iOS 11.0, *)){
[[UIScrollView appearance] setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
}
OK,完美解决问题。
二、TabBar 在 push 的时候会向上弹,然后还会有黑块。
解决了第一个问题,紧接着第二个问题又来了,push时,tabBar隐藏,tabBar会往上偏移,并带有黑块出现,非常影响视觉,这个不能忍,必须解决,问题看图:
通过看@臭码农大大的简书解决了问题,解决方法是在自定义的navigationController中重写的push方法里面修改tabbar的frame,代码如下:
// 修改tabBar的frame 不然iPhone X push的时候tabBar上会向上弹
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (self.viewControllers.count > 0) {
viewController.hidesBottomBarWhenPushed = YES;
}
[super pushViewController:viewController animated:animated];
CGRect frame = self.tabBarController.tabBar.frame;
frame.origin.y = [UIScreen mainScreen].bounds.size.height - frame.size.height;
self.tabBarController.tabBar.frame = frame;
}
三、tableView cell自动计算高度失效了。
这个问题是突然在一个页面发现的,不知道为啥,突然自定义的cell自动计算高度无效了,运行起来一堆乱布局,当时可把我急坏了,到处找问题,还跑到Xcode8.3中去找问题,都没解决。self.tableView.estimatedRowHeight设置了也没用,后来无意间发现了个东西,简直像发现了新大陆一样,在Xcode9中在xib中设置的tableView需要勾选是否Automatic。
简直了,勾选后就可以了。
四、适配iPhone X,针对底部有按钮或者顶部有按钮的情况。
iPhone X出来后,多了个刘海和下面的触发交互行为的按钮,苹果官方要求,这两个区域是非安全区域,不能有功能性按钮,当我们有功能性按钮是,需要放在安全区里面的。所以当我们底部或者顶部有自定义的View时,需要放在安全区域内。
顶部我们可以这样:
// 适配iPhone X
if (@available(iOS 11.0, *)){
self.navView.frame = CGRectMake(0, self.view.safeAreaInsets.top, self.view.width, 64);
} else {
[self.navView mas_updateConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.mas_topLayoutGuide);
}];
}
// 重新设置navView下方的view的frame
CGRect frame = self.webView.frame;
frame.origin.y = CGRectGetMaxY(self.navView.frame);
self.webView.frame = frame;
底部:
// 适配iPhone X
if (@available(iOS 11.0, *)){
self.confirmBtn.frame = CGRectMake(0, self.view.height - self.view.safeAreaInsets.bottom - 48, self.view.width, 48);
} else {
[self.confirmBtn mas_updateConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(self.mas_bottomLayoutGuide);
}];
}
// 重新给confirmBtn上方的View设置frame
CGRect frame = self.tableView.frame;
frame.size.height = self.confirmBtn.frame.origin.y;
self.tableView.frame = frame;
当然了这两个设置都是放在 viewDidLayoutSubviews 方法里进行的。
好了,总的遇到的就这些问题,欢迎交流。
以上参考资料来自@臭码农的简书