iOS頁面布局:UIScrollView的布局問題

一、簡述

在iOS11以后的系統(tǒng)中UIViewControllerautomaticallyAdjustsScrollViewInsets這個屬性過期棄用了不再建議使用了。系統(tǒng)推薦我們使用UIScrollViewcontentInsetAdjustmentBehavior屬性替代它。如果項(xiàng)目之前使用了self. automaticallyAdjustsScrollViewInsets = YES,并且設(shè)置scrollView.contentInset的值,此時(shí)升級到iOS11以上的系統(tǒng)時(shí)頁面就會出現(xiàn)布局問題。下面簡單的寫下關(guān)于contentInsetAdjustmentBehavior這個屬性的理解。關(guān)于這個屬性提供了四種設(shè)置值。

備注:當(dāng)UIScrollViewframe超出安全區(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ū)域,只要UIScrollViewframe超出安全區(qū)域就調(diào)整相應(yīng)top&bottom的超出值,調(diào)整的最大值不會超過安全區(qū)相應(yīng)方向的距離的最大值。

  • 如何計(jì)算adjustContentInset值:

adjustContentInset = safeAreaInset + contentInset

三、測試

  • 測試一: 默認(rèn)設(shè)置 contentInsetAdjustmentBehaviorAutomatic,頁面延伸布局為整個屏幕,從屏幕頂端開始計(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è)置 contentInsetAdjustmentBehaviorAutomatic,頁面延伸布局為整個屏幕,從屏幕頂端開始計(jì)算,并且設(shè)置UITableViewcontentInset的值為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è)置 contentInsetAdjustmentBehaviorAutomatic,頁面延伸布局為整個屏幕,從屏幕頂端開始計(jì)算,并且設(shè)置UITableView的frame的y值為50;
圖3
view.safeAreaInsets = {88, 0, 83, 0}
tableView.contentInset = {0, 0, 0, 0}
tableView.adjustedContentInset = {38, 0, 83, 0}
  • 測試四: 默認(rèn)設(shè)置 contentInsetAdjustmentBehaviorAutomatic,頁面延伸布局為整個屏幕,從屏幕頂端開始計(jì)算,并且設(shè)置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的內(nèi)容顯示正常,并且調(diào)整值小于安全區(qū)域垂直方向的最大值;
由圖4可見,在UITableView的頂部偏移父view的頂端-50像素,上移,在此配置下UITableView的內(nèi)容顯示不正常,并且調(diào)整值為安全區(qū)域垂直方向的最大值;

結(jié)合圖3和圖4,可證明調(diào)整的最大值不會超過安全區(qū)相應(yīng)方向的距離的最大值。

  • 測試五: 設(shè)置 contentInsetAdjustmentBehaviorNever,頁面延伸布局為整個屏幕,從屏幕頂端開始計(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。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容