全屏布局(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必须是根视图添加的第一个子视图,否则此属性无效。

最后

这都是作者在实际工作中的一些总结,如有不对之处,欢迎指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • /* UIViewController is a generic controller base class th...
    DanDanC阅读 5,918评论 0 2
  • 1.badgeVaule气泡提示 2.git终端命令方法> pwd查看全部 >cd>ls >之后桌面找到文件夹内容...
    i得深刻方得S阅读 10,266评论 1 9
  • *7月8日上午 N:Block :跟一个函数块差不多,会对里面所有的内容的引用计数+1,想要解决就用__block...
    炙冰阅读 7,361评论 1 14
  • 嗨,你们好 嗨,好久不见 叮咚,门铃响了 一如既往的打开一扇门,二扇门 突然来了一句:“小王,今天让你做的,做完了...
    _似锦年华阅读 3,388评论 0 2
  • 无意遇到简书,看着下载评论里很多人因简书而兴奋和满足,被他们感染了,也下载了下来。对于我这种接受填鸭式教育且...
    f29e1084117a阅读 1,418评论 0 0

友情链接更多精彩内容