如何在不启用Autolayout时使用Safe Area Layout Guide适配iPhone X?
不用AutoLayout适配iPhone X的解决方案(部署目标iOS8)
我来帮你搞定这个问题!因为Safe Area Layout Guide确实和AutoLayout绑定死了,勾选它就会自动开启AutoLayout,所以咱们得换个手动处理的路子,完全不用AutoLayout也能适配iPhone X,还能兼容你的iOS8部署目标。
1. 先把Storyboard的设置调对
- 打开你的视图控制器对应的Storyboard,选中视图控制器后,在右侧属性面板里取消勾选「Use Auto Layout」(要是之前被自动勾上了就去掉),别碰「Use Safe Area Layout Guide」那个选项,碰了就触发AutoLayout了。
- 还要确保你所有子视图的
autoresizingMask设置符合需求——比如要让视图跟着父视图宽高自适应的话,就在属性面板里勾上对应的「Flexible Width」和「Flexible Height」选项。
2. 先让应用能在iPhone X上全屏显示
这步很关键!要是没弄好,后面适配都是白搭:
- 要么用Launch Screen.storyboard(推荐,一劳永逸适配所有设备),要么给iPhone X添加对应的启动图(尺寸是1125x2436像素),不然应用在iPhone X上会留黑边,没法全屏显示。
3. 手动计算安全区域边距,调整视图布局
iPhone X只在iOS11及以上的系统里运行,iOS8到iOS10根本没有这个设备,所以咱们只需要针对iOS11+的设备处理顶部刘海和底部Home Indicator的边距就行。
Objective-C代码实现
在你的视图控制器里重写viewDidLayoutSubviews方法,手动调整内容视图的frame:
- (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; CGFloat topInset = 0.0; CGFloat bottomInset = 0.0; // 只有iOS11及以上的系统能获取安全区域边距 if (@available(iOS 11.0, *)) { topInset = self.view.safeAreaInsets.top; bottomInset = self.view.safeAreaInsets.bottom; } // 调整内容视图的frame,避开刘海和Home Indicator CGRect contentFrame = self.view.bounds; contentFrame.origin.y = topInset; contentFrame.size.height -= (topInset + bottomInset); // 假设你的内容容器是contentView,设置它的frame并保持自适应 self.contentView.frame = contentFrame; self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; }
Swift代码实现
override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() var topInset: CGFloat = 0.0 var bottomInset: CGFloat = 0.0 if #available(iOS 11.0, *) { topInset = view.safeAreaInsets.top bottomInset = view.safeAreaInsets.bottom } var contentFrame = view.bounds contentFrame.origin.y = topInset contentFrame.size.height -= (topInset + bottomInset) contentView.frame = contentFrame contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight] }
4. 额外要注意的小细节
- 要是你有贴近底部的元素(比如底部按钮),别直接把它固定到父视图的底部,而是固定到
contentView的底部,这样在iPhone X上就会自动避开Home Indicator了。 - 关于状态栏高度:iOS11+的
safeAreaInsets.top已经包含了状态栏的高度(iPhone X是44pt,其他设备是20pt或者0pt),所以不用单独去计算状态栏高度啦。
内容的提问来源于stack exchange,提问作者JAK
相关产品推荐
相关产品推荐

