影响界面布局的相关属性
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)
位置处,此时上滑将会形成穿透效果导航栏的效果。
补充:当你的设计中出现导航栏穿透效果
,自定义非透明的导航栏背景
、导航栏完全透明
等需求时,记得结合上述几点进行判断处理,避免发生预想之外的界面偏差。