112

想APP在爱疯X上运行正常?那么你必须知道这些适配的关键点! - 恒生技术之眼 - 恒生研...

 6 years ago
source link: http://rdc.hundsun.com/portal/article/828.html?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

想APP在爱疯X上运行正常?那么你必须知道这些适配的关键点!

期待已久的苹果秋季发布会发布了 iPhone 十周年纪念版:iPhone X。与大家不同的是,程序员更关注的是这次iPhone X的外形改动。如何能让自己的APP在iPhone X正常而且不失设计感地运行,iPhone X的外形适配就显得非常重要了。本文我们就谈谈在IPhone X适配上遇到的一些问题以及关注点。

【启动页尺寸】

iPhone X 采用了 2436*1125 分辨率,屏幕高宽长度为812*375,拥有一块大约 2.17:1 的屏幕。

f_5e24d04d4dac957d142e7732929b9893.png

iPhone X 的屏幕像素比 iPhone 8 高出 145 pt。适配 iPhone X 时使用 @3x 即可。
▪ 如果之前的项目里面使用Assets.xcassets来使用启动图的配置的话,可增加一张2436*1125 分辨率的名称中@3x使用即可。
▪  如果使用LaunchScreen.storyboard的话,则不需要修改,只用关注viewcontroller的页面布局就可以。

【导航栏和底部工具栏】

由于iPhone X引入了虚拟home区域和刘海会导致一些主屏幕的内容显示不全或者被遮挡的情况,所以需要进行一些UI适配。

f_c1bfb5ed19ef6f152e0e76d323d5a769.png

iPhone X以外的机型导航栏的高度是64,其中statusBar的高度为20,而iPhone X的statusBar高度变为了44,如果是自定义的navigationBar,这部分需要做相应的适配。

iPhone X的底部增加了虚拟Home区域,由于安全区域的原因,默认tabBar的高度由49变为83,增高了34,所以自定义的底部TabBar也需要改其适配方案。按照系统的tabbarViewController显示的结果,默认会将Tabbar提高布局34。

【安全区域】

安全区域定义了view中可视区域的部分,帮助我们将view放置在整个屏幕可视的部分。即使把navigationbar设置为透明,系统也认为安全区域是从navigationbar的bottom开始的。这样保证不被系统的状态栏、或父视图提供的view如导航栏覆盖。

f_c68290efdc6d83f9908dcbd0030339e8.png

适配场景
导航栏
如果含有菜单栏时不需要进行适配,因为系统已经帮忙做好适配,如果没有菜单栏时,需要适配不置顶到状态栏。

▪ 菜单栏
使用系统的菜单栏tabbarVC的话,系统已经帮助开发者做好底部适配,不会置顶至底部虚拟Home区域。如果自定义tabbar的话,需要注意tabbar的放置区域,不要置顶底部。

▪ 内容区域
如果内容上有可操作的界面置顶到底部或者头部,需要做对内容区域进行压缩至安全区域。如果内容只是内容显示,可置顶至头部或者底部,具体页面适配可通过具体业务进行处理,只要不出现遮挡问题即可。

以上所讨论的适配情况都需要安全区域进行处理,下面就说下如何在代码中使用安全区域。

safeAreaInses
在iOS11版本中
UIViewController和UIView新加了-(void)viewSafeAreaInsetsDidChange方法,当安全区域改变后该方法会被调用。然后在该方法中根据safeAreaInses属性更新子视图中控件的布局位置。如果不是在viewSafeAreaInsetsDidChange在这个方法中或者过早地取值safeAreaInses属性的话,获取的值会是UIEdgeInsetsZero。

当然如果你要改变一个UIViewController的safeAreaInsets值, 可以通过设置addtionalSafeAreaInsets属性来实现, 例如你要自定义一些特殊的样式时,在状态栏上做一些布局设计之类。

需要注意的是这里需要提一点,viewSafeAreaInsetsDidChange方法会被调用多次。viewSafeAreaInsetsDidChange在UIViewController中第一次调用的是在-(void)viewWillAppear:(BOOL)animated调用之后, 在- (void)viewWillLayoutSubviews调用之前。所以可以在viewWillAppear里设置受影响的页面的addtionalSafeAreaInsets属性。

safeAreaLayoutGuide
另外Apple在iOS 7中引入了topLayoutGuide和bottomLayoutGuide作为UIViewController属性。它们允许创建约束,以保持内容不被状态,导航或标签栏等UIKit栏隐藏。 这些布局指南在iOS 11中已被弃用,并被safeAreaLayoutGuide取代。

如果使用xib或者storyboard进行ui适配的话可以在xib上选择 userSafeAreaLayoutGuides

f_64b4cbb0097019dd878bd4ad02e4d6cc.png

故事板自动将顶部和底部布局指南替换为安全区域,并更新约束。

如若使用代码进行自动布局时,可以进行如下编码  

f_ff6e94c4d45c0a52c0a47cd4940e7e29.png
f_0f255de8ab617e0b19fb25dfea71c204.png

以上锚点约束属于IOS11才有的方法。使用该方法不会撑满整个屏幕,会留出外边8pt的距离,如果想要view撑满viewController的话,还是需要使用constraintEqualToAnchor,以上的方法只是对于NSLayoutXAxisAnchor,其他的锚点新方法也有对应的增加,可查询API

例如某组件做了如下适配:

f_e15843bdc77737091e00155a775d6cf0.png
f_2d8e07b3ca2783d71fac8aac1b737be8.png

保证在可操作内容在安全区域范围内。

【UI控件的使用事项】

▲UIScrollView & UITableView
由于iOS 11已经弃用了UIViewController的automaticallyAdjustsScrollViewInsets属性,新增了contentInsetAdjustmentBehavior属性,所以当超出安全区域时,系统自动调整了SafeAreaInsets,进而影响了adjustedContentInset,在iOS11中决定tableView内容与边缘距离的是adjustedContentInset,所以需要设置UIScrollView的contentInsetAdjustmentBehavior属性。

手动适配
UIScrollView的contentInsetAdjustmentBehavior属性值设置为UIScrollViewContentInsetAdjustmentNever,系统不会主动为你设置边缘距离,但是你可能需要手动适配UITableView的contenteInset。 

▪ 自动适配
设置contentInsetAdjustmentBehavior属性为UIScrollViewContentInsetAdjustmentAutomatic,则系统会自动计算contentView的偏移量。

iOS11开始UITableView开启了自动估算行高,estimatedRowHeight estimatedSectionHeaderHeight estimatedSectionFooterHeight三个高度估算属性由默认的0变成了UITableViewAutomaticDimension(行高的默认值),所以heightForHeaderInSection和viewForHeaderInSection应该一起使用,不然tableView顶部滑动的时候会有空白。

据网上友人说,在适配过程中发现UITableView会在Header/Footer返回size为负值的情况下会崩溃,而iOS11之前的版本不会。

【底部弹出控件】

在一些底部弹出控件上,IOS在原生控件上已经做了phoneX的适配,比如键盘,UIAlertSheet,都已经做了对应虚拟Home键区域的适配。
例如某搜索键盘适配如下:

f_f629fcff7c9bc53a57701cfeaaf7e3fa.png

如果自定义底部控件以及键盘的内容在虚拟home键区域中有按键按钮布局,需要重新设计控件UI,可适当上移控件,避免内容遮盖。

参考文献:
• Designing for iPhone X
• iOS11/iPhoneX最新适配指南


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK