新版本iOS系統趨向于盡可能完全利用有限的屏幕以展示更多的用戶數據,所以UINavigationBar和UITabBar默認都是半透明模糊效果,UIScrollView中的內容在它們后面也是隱約可見的。
在此情況下,系統對于作為controller view的第一個subView的全屏UIScrollView,會自動處理其contentInset,使其頭部和尾部的內容起始和末尾時不會被UINavigationBar和UITabBar擋住。但是如果你關閉系統這一自動功能的話:
self.automaticallyAdjustsScrollViewInsets = NO;
UIScrollView的內容就會從frame的(0,0)位置開始顯示,這樣開頭就被UINavigationBar,尾部就被UITabBar擋住而只能看到模糊一片,除非用戶使勁下拉上拉。這時就需要你自己去設置contentInset了。
與此同時,由于現在view的frame都是從(0,0)開始,對于非UIScrollView及其子類就會有些麻煩了,因為如果子控件frame如果不考慮UINavigationBar的高度,就會被UINavigationBar擋住,當然我們可以自己在布局的時候加上UINavigationBar的高度就行了。
其實還有一種更方便的方法就是設置其edgesForExtendedLayout屬性,該屬性默認為UIRectEdgeAll,意為view會充分擴展至屏幕邊緣包括上下左右,而不管有沒有遮擋,此時就是view的frame即為整個屏幕。但是不像UIScrollView,其它view沒有contentInset一說,所以automaticallyAdjustsScrollViewInsets對其并不起作用。此時,我們修改edgesForExtendedLayout屬性:
self.edgesForExtendedLayout = UIRectEdgeNone;
系統就會自動根據UINavigationBar和statusBar將view下移64,frame從(0,64)開始。這樣,我們在布局內部控件的時候依然可以從(0,0)開始,而不必擔心上部被UINavigationBar遮擋了。
另一種情況就是我們不想要那種半透明模糊效果,設置UINavigationBar的translucent為NO。此時,view的frame也都會從(0,64)開始,而此時對于UIScrollView,automaticallyAdjustsScrollViewInsets就不再起作用了。
總結:UIScrollView如果要實現穿透UINavigationBar的效果,其frame就必須從(0,0)開始,然后設置合適的contentInset,如果UINavigationBar下方還有懸浮view的話,就不能依賴系統的automaticallyAdjustsScrollViewInsets了,需要自己來算contentInset。還有其他的特殊需求,就需要組合使用以上屬性了。