iOS页面布局:UIScrollView的布局问题

简介: iOS页面布局:UIScrollView的布局问题

一、简述
在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

  1. UIScrollViewContentInsetAdjustmentAutomatic
    默认值,scrollView会根据页面的安全区域的值自动调整计算,系统在计算content的edgeInset时会考虑到安全区域自动计算和适应顶部和底部的内边距。即使UIScrollView不可滚动,也会自动设置content的内边距。其他情况下行为与UIScrollViewContentInsetAdjustmentScrollableAxes相同。

如何计算adjustContentInset值:
adjustContentInset = safeAreaInset + contentInset

  1. UIScrollViewContentInsetAdjustmentScrollableAxes
    也是自动调整计算,但是会考虑滚动方向,系统会根据UIScrollView的滚动方向进行判断内容的内边距是否要考虑安全区域,依赖于scrollEnabled和alwaysBounceHorizontal / vertical = YES。
    eg. 如果是一个横向滚动的UIScrollView,及便布局起点和高度值超过了页面的安全区,那么系统也不会调整。

如何计算adjustContentInset值:
可滚动方向:

adjustContentInset = safeAreaInset + contentInset

不可滚动方向:

adjustContentInset = contentInset
  1. UIScrollViewContentInsetAdjustmentNever
    内容的内边距从不考虑安全区域,当contentInsetAdjustmentBehavior设置为Never的时候,adjustContentInset值不受SafeAreaInset值的影响。
    eg. 就算UIScrollView超出了safeAreaInsets,系统不会对你的scrollView.adjustedContentInset做任何事情,即不作任何调整。

如何计算adjustContentInset值:

adjustContentInset = contentInset
  1. UIScrollViewContentInsetAdjustmentAlways
    内容的内边距总是考虑安全区域,只要UIScrollView的frame超出安全区域就调整相应top&bottom的超出值,调整的最大值不会超过安全区相应方向的距离的最大值。

如何计算adjustContentInset值:

adjustContentInset = safeAreaInset + contentInset

三、测试
测试一: 默认设置 contentInsetAdjustmentBehavior为Automatic,页面延伸布局为整个屏幕,从屏幕顶端开始计算;
image.png
图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);
image.png
图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;
image.png
图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;

image.png
图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,页面延伸布局为整个屏幕,从屏幕顶端开始计算;

image.png
图五

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。

相关文章
|
Swift iOS开发
iOS 用一个布局来解决嵌套问题—— UICollectionViewCompositionalLayout
iOS 用一个布局来解决嵌套问题—— UICollectionViewCompositionalLayout
iOS 用一个布局来解决嵌套问题—— UICollectionViewCompositionalLayout
|
iOS开发
iOS布局中的抗被拉伸、抗压缩优先级
iOS布局中的抗被拉伸、抗压缩优先级
594 0
|
API iOS开发 开发者
iOS文本布局探讨之三——使用TextKit框架进行富文本布局
iOS文本布局探讨之三——使用TextKit框架进行富文本布局
386 0
iOS文本布局探讨之三——使用TextKit框架进行富文本布局
|
编解码 Android开发 iOS开发
IOS使用AutoLayout让UIScrollView自动计算ContentSize
IOS使用AutoLayout让UIScrollView自动计算ContentSize
177 0
|
iOS开发
IOS15上纯代码布局之导航控制器的导航条为透明的问题
IOS15上纯代码布局之导航控制器的导航条为透明的问题
216 0
|
iOS开发
IOS使用纯代码布局替换掉默认的storyboard
IOS使用纯代码布局替换掉默认的storyboard
98 0
|
Android开发 iOS开发
IOS开发之UIScrollView约束布局
IOS开发之UIScrollView约束布局
407 0
|
Android开发 iOS开发
IOS的UIScrollview简单使用
IOS的UIScrollview简单使用
84 0
|
iOS开发
iOS 利用UIScrollView实现图片放大预览,并支持缩小
iOS 利用UIScrollView实现图片放大预览,并支持缩小
502 0
iOS 利用UIScrollView实现图片放大预览,并支持缩小