一、简述
在iOS11以后的系统中UIViewController的automaticallyAdjustsScrollViewInsets这个属性过期弃用了不再建议使用了。系统推荐我们使用UIScrollView的contentInsetAdjustmentBehavior属性替代它。如果项目之前使用了self. automaticallyAdjustsScrollViewInsets = YES,并且设置scrollView.contentInset的值,此时升级到iOS11以上的系统时页面就会出现布局问题。下面简单的写下关于contentInsetAdjustmentBehavior这个属性的理解。关于这个属性提供了四种设置值。
备注:当UIScrollView的frame超出安全区域时,contentInsetAdjustmentBehavior决定了adjustContentInset的计算方式是否会受到safeAreaInset安全区域值的影响,进而影响了adjustContentInset的最终值。最终影响到UIScrollView的content的内边距。
typedef NS_ENUM(NSInteger, UIScrollViewContentInsetAdjustmentBehavior) {
UIScrollViewContentInsetAdjustmentAutomatic,
UIScrollViewContentInsetAdjustmentScrollableAxes,
UIScrollViewContentInsetAdjustmentNever,
UIScrollViewContentInsetAdjustmentAlways,
}
二、UIScrollViewContentInsetAdjustmentBehavior 和 adjustContentInset
- UIScrollViewContentInsetAdjustmentAutomatic
默认值,scrollView会根据页面的安全区域的值自动调整计算,系统在计算content的edgeInset时会考虑到安全区域自动计算和适应顶部和底部的内边距。即使UIScrollView不可滚动,也会自动设置content的内边距。其他情况下行为与UIScrollViewContentInsetAdjustmentScrollableAxes相同。
如何计算adjustContentInset值:
adjustContentInset = safeAreaInset + contentInset
- UIScrollViewContentInsetAdjustmentScrollableAxes
也是自动调整计算,但是会考虑滚动方向,系统会根据UIScrollView的滚动方向进行判断内容的内边距是否要考虑安全区域,依赖于scrollEnabled和alwaysBounceHorizontal / vertical = YES。
eg. 如果是一个横向滚动的UIScrollView,及便布局起点和高度值超过了页面的安全区,那么系统也不会调整。
如何计算adjustContentInset值:
可滚动方向:
adjustContentInset = safeAreaInset + contentInset
不可滚动方向:
adjustContentInset = contentInset
- UIScrollViewContentInsetAdjustmentNever
内容的内边距从不考虑安全区域,当contentInsetAdjustmentBehavior设置为Never的时候,adjustContentInset值不受SafeAreaInset值的影响。
eg. 就算UIScrollView超出了safeAreaInsets,系统不会对你的scrollView.adjustedContentInset做任何事情,即不作任何调整。
如何计算adjustContentInset值:
adjustContentInset = contentInset
- UIScrollViewContentInsetAdjustmentAlways
内容的内边距总是考虑安全区域,只要UIScrollView的frame超出安全区域就调整相应top&bottom的超出值,调整的最大值不会超过安全区相应方向的距离的最大值。
如何计算adjustContentInset值:
adjustContentInset = safeAreaInset + contentInset
三、测试
测试一: 默认设置 contentInsetAdjustmentBehavior为Automatic,页面延伸布局为整个屏幕,从屏幕顶端开始计算;
图1
由图1可见,在默认配置下UITableView的内容显示正常,其内容的内边距计算考虑到了安全距离。
view.safeAreaInsets = {
88, 0, 83, 0}
tableView.contentInset = {
0, 0, 0, 0}
tableView.adjustedContentInset = {
88, 0, 83, 0}
测试二: 默认设置 contentInsetAdjustmentBehavior为Automatic,页面延伸布局为整个屏幕,从屏幕顶端开始计算,并且设置UITableView的contentInset的值为UIEdgeInsetsMake(40, 0, 0, 0);
图2
由图2可见,在此配置下UITableView的内容显示不正常,UITableView的内容的内边距向下偏移了40
view.safeAreaInsets = {
88, 0, 83, 0}
tableView.contentInset = {
40, 0, 0, 0}
tableView.adjustedContentInset = {
128, 0, 83, 0}
测试三: 默认设置 contentInsetAdjustmentBehavior为Automatic,页面延伸布局为整个屏幕,从屏幕顶端开始计算,并且设置UITableView的frame的y值为50;
图3
view.safeAreaInsets = {
88, 0, 83, 0}
tableView.contentInset = {
0, 0, 0, 0}
tableView.adjustedContentInset = {
38, 0, 83, 0}
测试四: 默认设置 contentInsetAdjustmentBehavior为Automatic,页面延伸布局为整个屏幕,从屏幕顶端开始计算,并且设置UITableView的frame的y值为-50;
图4
view.safeAreaInsets = {
88, 0, 83, 0}
tableView.contentInset = {
0, 0, 0, 0}
tableView.adjustedContentInset = {
88, 0, 83, 0}
由图3可见,在UITableView的顶部偏移父view的顶端50像素,下移,在此配置下UITableView的内容显示正常,并且调整值小于安全区域垂直方向的最大值;
由图4可见,在UITableView的顶部偏移父view的顶端-50像素,上移,在此配置下UITableView的内容显示不正常,并且调整值为安全区域垂直方向的最大值;
结合图3和图4,可证明调整的最大值不会超过安全区相应方向的距离的最大值。
测试五: 设置 contentInsetAdjustmentBehavior为Never,页面延伸布局为整个屏幕,从屏幕顶端开始计算;
图五
view.safeAreaInsets = {
88, 0, 83, 0}
tableView.contentInset = {
0, 0, 0, 0}
tableView.adjustedContentInset = {
0, 0, 0, 0}
由图5可见,在设置为Never时,UITableView的内容内边距不会再考虑安全区域,因此系统计算adjustedContentInset的调整至为0,页面布局显示异常,此时adjustedContentInset = contentInset。