一、簡述
在iOS11以后的系統(tǒng)中UIViewController的automaticallyAdjustsScrollViewInsets這個屬性過期棄用了不再建議使用了。系統(tǒng)推薦我們使用UIScrollView的contentInsetAdjustmentBehavior屬性替代它。如果項(xiàng)目之前使用了self. automaticallyAdjustsScrollViewInsets = YES,并且設(shè)置scrollView.contentInset的值,此時(shí)升級到iOS11以上的系統(tǒng)時(shí)頁面就會出現(xiàn)布局問題。下面簡單的寫下關(guān)于contentInsetAdjustmentBehavior這個屬性的理解。關(guān)于這個屬性提供了四種設(shè)置值。
備注:當(dāng)
UIScrollView的frame超出安全區(qū)域時(shí),contentInsetAdjustmentBehavior決定了adjustContentInset的計(jì)算方式是否會受到safeAreaInset安全區(qū)域值的影響,進(jìn)而影響了adjustContentInset的最終值。最終影響到UIScrollView的content的內(nèi)邊距。
typedef NS_ENUM(NSInteger, UIScrollViewContentInsetAdjustmentBehavior) {
UIScrollViewContentInsetAdjustmentAutomatic,
UIScrollViewContentInsetAdjustmentScrollableAxes,
UIScrollViewContentInsetAdjustmentNever,
UIScrollViewContentInsetAdjustmentAlways,
}
二、UIScrollViewContentInsetAdjustmentBehavior 和 adjustContentInset
1. UIScrollViewContentInsetAdjustmentAutomatic
默認(rèn)值,scrollView會根據(jù)頁面的安全區(qū)域的值自動調(diào)整計(jì)算,系統(tǒng)在計(jì)算content的edgeInset時(shí)會考慮到安全區(qū)域自動計(jì)算和適應(yīng)頂部和底部的內(nèi)邊距。即使UIScrollView不可滾動,也會自動設(shè)置content的內(nèi)邊距。其他情況下行為與UIScrollViewContentInsetAdjustmentScrollableAxes相同。
- 如何計(jì)算adjustContentInset值:
adjustContentInset = safeAreaInset + contentInset
2. UIScrollViewContentInsetAdjustmentScrollableAxes
也是自動調(diào)整計(jì)算,但是會考慮滾動方向,系統(tǒng)會根據(jù)UIScrollView的滾動方向進(jìn)行判斷內(nèi)容的內(nèi)邊距是否要考慮安全區(qū)域,依賴于scrollEnabled和alwaysBounceHorizontal / vertical = YES。
eg. 如果是一個橫向滾動的UIScrollView,及便布局起點(diǎn)和高度值超過了頁面的安全區(qū),那么系統(tǒng)也不會調(diào)整。
- 如何計(jì)算adjustContentInset值:
可滾動方向:
adjustContentInset = safeAreaInset + contentInset
不可滾動方向:
adjustContentInset = contentInset
3. UIScrollViewContentInsetAdjustmentNever
內(nèi)容的內(nèi)邊距從不考慮安全區(qū)域,當(dāng)contentInsetAdjustmentBehavior設(shè)置為Never的時(shí)候,adjustContentInset值不受SafeAreaInset值的影響。
eg. 就算UIScrollView超出了safeAreaInsets,系統(tǒng)不會對你的scrollView.adjustedContentInset做任何事情,即不作任何調(diào)整。
- 如何計(jì)算adjustContentInset值:
adjustContentInset = contentInset
4. UIScrollViewContentInsetAdjustmentAlways
內(nèi)容的內(nèi)邊距總是考慮安全區(qū)域,只要UIScrollView的frame超出安全區(qū)域就調(diào)整相應(yīng)top&bottom的超出值,調(diào)整的最大值不會超過安全區(qū)相應(yīng)方向的距離的最大值。
- 如何計(jì)算adjustContentInset值:
adjustContentInset = safeAreaInset + contentInset
三、測試
-
測試一: 默認(rèn)設(shè)置
contentInsetAdjustmentBehavior為Automatic,頁面延伸布局為整個屏幕,從屏幕頂端開始計(jì)算;
圖1
由圖1可見,在默認(rèn)配置下UITableView的內(nèi)容顯示正常,其內(nèi)容的內(nèi)邊距計(jì)算考慮到了安全距離。
view.safeAreaInsets = {88, 0, 83, 0}
tableView.contentInset = {0, 0, 0, 0}
tableView.adjustedContentInset = {88, 0, 83, 0}
-
測試二: 默認(rèn)設(shè)置
contentInsetAdjustmentBehavior為Automatic,頁面延伸布局為整個屏幕,從屏幕頂端開始計(jì)算,并且設(shè)置UITableView的contentInset的值為UIEdgeInsetsMake(40, 0, 0, 0);
圖2
由圖2可見,在此配置下UITableView的內(nèi)容顯示不正常,UITableView的內(nèi)容的內(nèi)邊距向下偏移了40
view.safeAreaInsets = {88, 0, 83, 0}
tableView.contentInset = {40, 0, 0, 0}
tableView.adjustedContentInset = {128, 0, 83, 0}
-
測試三: 默認(rèn)設(shè)置
contentInsetAdjustmentBehavior為Automatic,頁面延伸布局為整個屏幕,從屏幕頂端開始計(jì)算,并且設(shè)置UITableView的frame的y值為50;

view.safeAreaInsets = {88, 0, 83, 0}
tableView.contentInset = {0, 0, 0, 0}
tableView.adjustedContentInset = {38, 0, 83, 0}
-
測試四: 默認(rèn)設(shè)置
contentInsetAdjustmentBehavior為Automatic,頁面延伸布局為整個屏幕,從屏幕頂端開始計(jì)算,并且設(shè)置UITableView的frame的y值為-50;

view.safeAreaInsets = {88, 0, 83, 0}
tableView.contentInset = {0, 0, 0, 0}
tableView.adjustedContentInset = {88, 0, 83, 0}
由圖3可見,在UITableView的頂部偏移父view的頂端50像素,下移,在此配置下UITableView的內(nèi)容顯示正常,并且調(diào)整值小于安全區(qū)域垂直方向的最大值;
由圖4可見,在UITableView的頂部偏移父view的頂端-50像素,上移,在此配置下UITableView的內(nèi)容顯示不正常,并且調(diào)整值為安全區(qū)域垂直方向的最大值;
結(jié)合圖3和圖4,可證明調(diào)整的最大值不會超過安全區(qū)相應(yīng)方向的距離的最大值。
-
測試五: 設(shè)置
contentInsetAdjustmentBehavior為Never,頁面延伸布局為整個屏幕,從屏幕頂端開始計(jì)算;

view.safeAreaInsets = {88, 0, 83, 0}
tableView.contentInset = {0, 0, 0, 0}
tableView.adjustedContentInset = {0, 0, 0, 0}
由圖5可見,在設(shè)置為Never時(shí),UITableView的內(nèi)容內(nèi)邊距不會再考慮安全區(qū)域,因此系統(tǒng)計(jì)算adjustedContentInset的調(diào)整至為0,頁面布局顯示異常,此時(shí)adjustedContentInset = contentInset。

