影响界面布局的相关属性

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)位置处,此时上滑将会形成穿透效果导航栏的效果。

补充:当你的设计中出现导航栏穿透效果自定义非透明的导航栏背景导航栏完全透明等需求时,记得结合上述几点进行判断处理,避免发生预想之外的界面偏差。

原文地址:https://www.cnblogs.com/ShaRuru/p/10591741.html