Property | Class |
---|---|
edgesForExtendedLayout | UIViewController |
extendedLayoutIncludesOpaqueBars | UIViewController |
automaticallyAdjustsScrollViewInsets | UIViewController |
translucent | NavigationBar |
edgesForExtendedLayout屬性的系統默認值為UIRectEdgeAll:意味著當導航控制器的導航欄為半透明效果時,子控制器
self.view
布局的起始位置將從屏幕邊緣左上角開始。extendedLayoutIncludesOpaqueBars屬性系統默認為NO,
Opaque
代表非透明,not Includes
意味著導航欄不是半透明時,即便當前是UIRectEdgeAll,self.view的布局起始位置依舊是從導航欄下方開始。translucent屬性值會決定導航欄是否有半透明效果。translucent為NO,意味著導航欄為非透明,此時如上文所述,即便當前是UIRectEdgeAll,由于extendedLayoutIncludesOpaqueBars為默認NO,self.view的布局起始位置依舊是從導航欄下方開始。
需要特別注意的是:
根據官方文檔所述:translucent會受navigationBar的backgroudImage屬性的影響。也就是說當你使用了一張自定義圖片作為navigationBar的背景圖時,translucent的值將由系統根據該圖片是否顏色值透明,來推斷translucent是YES or NO。
于是坑就來了:對于導航控制器中的各個childViewController,是共用同一個的navigationBar。當你在一個childViewController中自定義了navigationBar的背景圖片,或是直接改變了translucent屬性,此時再push或pop到另一個childViewController時,更改導航欄的半透明效果可能會影響到頁面的布局起始位置,從而發生視圖發生跳動,出現“意外”的上下偏移。
舉個例子:從一個設置了導航欄不透明的控制器A,pop回到一個原本設置了導航欄透明的控制器B時,B頁面發生了下移。
為避免該情況,應該將控制器B的extendedLayoutIncludesOpaqueBars設置為YES;或是當B頁面viewWillAppear:時,再度將導航欄設置為半透明效果。
- 至于automaticallyAdjustsScrollViewInsets屬性,系統默認值為YES。意味著當導航控制器的childViewController.view的上層視圖為scollView類簇時,則系統會自動為該scrollView的contentInset(內邊距屬性)的Top值增加額外的
64
,于是內容就會下移64
。
以tableView為例,當你使用默認的創建方式,也就是UIRectEdgeAll+導航欄半透明的情況下,首行cell的位置將處于導航欄下方,也就是屏幕坐標系的
(0, 64)
位置處,此時上滑將會形成穿透效果導航欄的效果。
補充:當你的設計中出現導航欄穿透效果
,自定義非透明的導航欄背景
、導航欄完全透明
等需求時,記得結合上述幾點進行判斷處理,避免發生預想之外的界面偏差。