影響導航控制器中頁面布局的幾個屬性

Property Class
edgesForExtendedLayout UIViewController
extendedLayoutIncludesOpaqueBars UIViewController
automaticallyAdjustsScrollViewInsets UIViewController
translucent NavigationBar
  1. edgesForExtendedLayout屬性的系統默認值為UIRectEdgeAll:意味著當導航控制器的導航欄為半透明效果時,子控制器self.view布局的起始位置將從屏幕邊緣左上角開始。

  2. extendedLayoutIncludesOpaqueBars屬性系統默認為NOOpaque代表非透明,not Includes意味著導航欄不是半透明時,即便當前是UIRectEdgeAllself.view的布局起始位置依舊是從導航欄下方開始。

  3. translucent屬性值會決定導航欄是否有半透明效果。translucentNO,意味著導航欄為非透明,此時如上文所述,即便當前是UIRectEdgeAll,由于extendedLayoutIncludesOpaqueBars為默認NOself.view的布局起始位置依舊是從導航欄下方開始。
    需要特別注意的是:

根據官方文檔所述:translucent會受navigationBar的backgroudImage屬性的影響。也就是說當你使用了一張自定義圖片作為navigationBar的背景圖時,translucent的值將由系統根據該圖片是否顏色值透明,來推斷translucent是YES or NO。

于是坑就來了:對于導航控制器中的各個childViewController,是共用同一個的navigationBar。當你在一個childViewController中自定義了navigationBar的背景圖片,或是直接改變了translucent屬性,此時再pushpop到另一個childViewController時,更改導航欄的半透明效果可能會影響到頁面的布局起始位置,從而發生視圖發生跳動,出現“意外”的上下偏移。

舉個例子:從一個設置了導航欄不透明的控制器A,pop回到一個原本設置了導航欄透明的控制器B時,B頁面發生了下移。

為避免該情況,應該將控制器B的extendedLayoutIncludesOpaqueBars設置為YES;或是當B頁面viewWillAppear:時,再度將導航欄設置為半透明效果。

  1. 至于automaticallyAdjustsScrollViewInsets屬性,系統默認值為YES。意味著當導航控制器的childViewController.view的上層視圖為scollView類簇時,則系統會自動為該scrollViewcontentInset(內邊距屬性)的Top值增加額外的64,于是內容就會下移64

tableView為例,當你使用默認的創建方式,也就是UIRectEdgeAll+導航欄半透明的情況下,首行cell的位置將處于導航欄下方,也就是屏幕坐標系的(0, 64)位置處,此時上滑將會形成穿透效果導航欄的效果。

補充:當你的設計中出現導航欄穿透效果自定義非透明的導航欄背景導航欄完全透明等需求時,記得結合上述幾點進行判斷處理,避免發生預想之外的界面偏差。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容