全屏布局(fullScreenLayout)那些事

圖片來源@百度圖片

當我們使用UINavigationController時,插入一個控制器,然后往這個控制器的view上加subview(比如一個tableView)時,經常會碰到tableView的實際展示跟自己設置的frame不一致的情況。這里就總結記錄一下平時自己遇到過的相關問題。

iOS7之前控制器有一個屬性wantsFullScreenLayout。當把它設置為YES時,你添加的subview的y就是從屏幕的最頂部開始算,包含navigationbar,設置為NO時,則從navigationbar的bottom開始算。因為iOS7之前,navigationbar默認一般是不透明的,所以wantsFullScreenLayout一般默認為NO。從iOS7開始,這個屬性被廢棄了,代替它的是三個新的屬性:edgesForExtendedLayoutextendedLayoutIncludesOpaqueBarsautomaticallyAdjustsScrollViewInsets,今天重點說的就是這三個經常用的屬性。

edgesForExtendedLayout

The extended edges to use for the layout.
This property is applied only to view controllers that are embedded in a container such as UINavigationController. The window’s root view controller does not react to this property. The default value of this property is UIRectEdgeAll

這個屬性是通過擴展子視圖的邊緣來適配屏幕,因為iOS7之后鼓勵全屏,navigationbar變得半透明,所以這個屬性默認為UIRectEdgeAll,及x和y是從屏幕的左上角開始算的。比如設置tableView的frame如下:

self.tableView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 350);

這里為了防止automaticallyAdjustsScrollViewInsets的干擾,我們在viewDidAppear:方法里加上一句代碼,下文會細說。

// 相當于把automaticallyAdjustsScrollViewInsets設置為NO了
self.tableView.contentInset = UIEdgeInsetsZero;

效果如下圖:

UIRectEdgeAll

當如下更改edgesForExtendedLayout的設置時

self.edgesForExtendedLayout = UIRectEdgeNone;

效果如下:

UIRectEdgeNone

顯然這是我們要的tableView效果,但是我們發現navigationbar的顏色變灰了,這是因為navigationbar是半透明的,但是navigationbar下面沒有視圖。

這時我們可以通過改變navigationbar的透明度來實現。

self.navigationController.navigationBar.translucent = NO;   
//    self.edgesForExtendedLayout = UIRectEdgeNone;

設置不透明之后,subview的邊緣就擴展不到頂部上了,只能到navigationbar的底部。效果

extendedLayoutIncludesOpaqueBars

A Boolean value indicating whether or not the extended layout includes opaque bars.
The default value of this property is NO

這個屬性是指當navigationbar不透明時,layout是否包含navigationbar。當navigationbar透明時,此屬性不起作用。比如在上面設置不透明的基礎上,把這個屬性設置為YES(該屬性默認NO),

self.navigationController.navigationBar.translucent = NO;  
//    self.edgesForExtendedLayout = UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars = YES;

發現tableView的y從屏幕最頂部開始算了。

extendedLayoutIncludesOpaqueBars

automaticallyAdjustsScrollViewInsets

A Boolean value that indicates whether the view controller should automatically adjust its scroll view insets.
The default value of this property is YES, which lets container view controllers know that they should adjust the scroll view insets of this view controller’s view to account for screen areas consumed by a status bar, search bar, navigation bar, toolbar, or tab bar. Set this property to NO if your view controller implementation manages its own scroll view inset adjustments.

這個屬性太強大了,它會根據navigationbar和tabbar的存在,自動調整scrollView的contentInset。如下圖

automaticallyAdjustsScrollViewInsets

透過半透明的navigationbar可以看到tableView的y其實還是在屏幕的最頂部,但是第一個cell已經變成從navigationbar的底部開始了,這是因為automaticallyAdjustsScrollViewInsets屬性默認為YES,tableView的contentInset已經由UIEdgeInsetsZero自動調整為UIEdgeInsetsMake(64, 0, 0, 0)了。當我們設置self.automaticallyAdjustsScrollViewInsets = NO;時,就變成上文第一張效果圖的效果了。但是它也有不足,就是scrollview必須是根視圖添加的第一個子視圖,否則此屬性無效。

最后

這都是作者在實際工作中的一些總結,如有不對之處,歡迎指正。

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

推薦閱讀更多精彩內容

  • /* UIViewController is a generic controller base class th...
    DanDanC閱讀 1,862評論 0 2
  • 1.badgeVaule氣泡提示 2.git終端命令方法> pwd查看全部 >cd>ls >之后桌面找到文件夾內容...
    i得深刻方得S閱讀 4,770評論 1 9
  • *7月8日上午 N:Block :跟一個函數塊差不多,會對里面所有的內容的引用計數+1,想要解決就用__block...
    炙冰閱讀 2,553評論 1 14
  • 嗨,你們好 嗨,好久不見 叮咚,門鈴響了 一如既往的打開一扇門,二扇門 突然來了一句:“小王,今天讓你做的,做完了...
    _似錦年華閱讀 495評論 0 2
  • 無意遇到簡書,看著下載評論里很多人因簡書而興奮和滿足,被他們感染了,也下載了下來。對于我這種接受填鴨式教育且...
    f29e1084117a閱讀 178評論 0 0