edgesForExtendedLayout

明确一下以前一知半解的属性吧,文中所有的代码都默认写在UIViewController中,所以self特指控制器。
阅读时注意“bar的低下”和“bar的bottom处”两种说法的区别(bar的低下是指层级关系,bar的bottom处是指frame中的位置关系)。

edgesForExtendedLayout

在IOS7以后 ViewController 开始使用全屏布局的,默认控制器内self.view是从屏幕最顶部左上角开始布局,并且不论是当前控制器是否嵌入在UINavigationController还是UITabBarController内,self.view默认占满整个屏幕,edgesForExtendedLayout的默认值为UIRectEdgeAll
如下图设置橙色视图为self.view,绿色视图加在self.view上,设置frame=self.view.bounds,所以两个视图都从屏幕最顶端开始布局,如果底部有tabbar(即UINavigationController还是嵌套在UITabBarController)self.view依然会延伸到屏幕的最底部

UIRectEdgeAll.png

由于上图会导致绿色视图被导航栏遮挡,我们想从导航栏的bottom处开始布局而还坚持想设置绿色视图的frame=self.view.bounds(因为自己写frame=CGRectMake()着实不爽),就可以设置控制器的edgesForExtendedLayout属性为UIRectEdgeNone,这样self.view就会从导航栏的botttom处开始布局:

UIRectEdgeNone.png
  • 哦,还有没说到的点是此属性仅适用于查看嵌入在容器(如UINavigationController)中的控制器。 窗口的根视图控制器不对此属性做出反应。
    edgesForExtendedLayout是UIRectEdge枚举类型:
typedef NS_OPTIONS(NSUInteger, UIRectEdge) {
    UIRectEdgeNone   = 0,
    UIRectEdgeTop    = 1 << 0,
    UIRectEdgeLeft   = 1 << 1,
    UIRectEdgeBottom = 1 << 2,
    UIRectEdgeRight  = 1 << 3,
    UIRectEdgeAll    = UIRectEdgeTop | UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight
} NS_ENUM_AVAILABLE_IOS(7_0);

可以自己尝试在控制器中分别设置看一下效果。

automaticallyAdjustsScrollViewInsets

下图层次结构为self.view->greenView->redView,设置self.edgesForExtendedLayout = UIRectEdgeAll(占满整个屏幕)
第一张图的greenView为UIScrollView对象,第二张图的greenView为UIView,观察greenView的子视图redView的布局位置


greenView为UIScrollView

greenView为UIView.png

当greenView为UIScrollView对象的时候redView从navigationBar的bottom处开始布局,这是因为控制器的automaticallyAdjustsScrollViewInsets属性默认为YES,

automaticallyAdjustsScrollViewInsets是一个布尔值,指示视图控制器是否应自动调整滚动视图的contentInset属性。以解决状态栏,搜索栏,导航栏,工具栏或选项卡栏所消耗的屏幕区域。 给contentInset属性中的上,左,下,右设置值,以避免滚动视图中的子视图被导航条,tabbar等遮挡住。
例如上图打印greenView的contentInset如下:

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    NSLog(@"%f-%f-%f-%f",self.greenView.contentInset.top,self.greenView.contentInset.left,self.greenView.contentInset.bottom,self.greenView.contentInset.right);
}

// 打印结果
2017-07-08 01:38:49.163 ZQNavigationBar[12648:786288] 64.000000-0.000000-0.000000-0.000000

greenView.contentInset.top被设置为了64,正好从导航栏bottom处开始布局,避免遮盖。
当设置self.automaticallyAdjustsScrollViewInsets = NO;时,greenView.contentInset将不会被自动设值,redView将从屏幕顶部开始布局

translucent

文档翻译如下:
指示导航栏是否为半透明(YES)的布尔值(否)。
默认值为YES。 如果导航栏具有自定义背景图像,则如果图像的任何像素的alpha值小于1.0,则默认值为YES,否则为否。
如果您在带有不透明的自定义背景图片的导航栏上将此属性设置为YES,则导航栏会将不足1.0的系统定义的不透明度应用于图像。
如果您在带有半透明自定义背景图片的导航栏上将此属性设置为NO,则如果导航栏具有UIBarStyleBlack样式,则导航栏将使用黑色为图像提供不透明的背景,如果导航栏具有UIBarStyleDefault,则为白色,或者导航栏的 barTintColor如果定义了自定义值。

可见关于导航条半透明,设置背景图片这一块幺蛾子甚多,慎重起见将另起文章进行研究,下图侧面证明了设置到导航条视觉效果设置的复杂性

下图层次结构为self.view->greenView->redView,都为UIView(避免受automaticallyAdjustsScrollViewInsets的干扰)

translucent为YES.png
translucent为NO.png

由图可见,设置self.navigationController.navigationBar.translucent = NO;时,不但导航条设置为不透明的了而且影响了self.view的布局开始位置(变成从导航条的bottom出开始布局了),导航条不透明了,导航条低下有什么颜色用户都看不到不能再提升视觉效果,干脆改变一下self.view的布局开始位置,方便开发人员——我猜猜的苹果爸爸的意图。实际上这里也可以控制self.view的布局从屏幕最顶部开始布局,如下图:

导航条不透明,self.view依然从屏幕顶部开始布局.png

导航条不透明,self.view依然从屏幕顶部开始布局。HOW???
刚刚学过了设置self.edgesForExtendedLayout = UIRectEdgeAll;可以让self.view占满整个屏幕,难道是这个吗?试一下,结果可见本文第二张图——并没有什么卵用,当设置self.navigationController.navigationBar.translucent = NO;时就要用到了extendedLayoutIncludesOpaqueBars属性

extendedLayoutIncludesOpaqueBars

文档:
一个布尔值,指示扩展布局是否包括不透明的条。
此属性的默认值为NO。
即:设置self.view的布局是否包含设置为不透明之后的导航条,tabbar之类的bar,如果设置了YES,依然会延伸到这些bar的下面,占满整个屏幕,如果设置NO就会避开这些bar,不会延伸到它们下面。上边的考虑是在self.edgesForExtendedLayout = UIRectEdgeAll;的基础之上,如果设置

// 扩展布局包括不透明的条
self.extendedLayoutIncludesOpaqueBars = YES;
// 导航条不透明
self.navigationController.navigationBar.translucent = NO;

然后设置

self.edgesForExtendedLayout = UIRectEdgeNone;

呢?结果:


最后一个图了.png

布局从导航条的botttom处开始!

结论(关于以上四个属性的py交易):

self.navigationController.navigationBar.translucent = YES;(导航条半透明)时,布局的扩展边界,从哪里开始布局受self.edgesForExtendedLayout属性的影响,

  • 当self.edgesForExtendedLayout = UIRectEdgeNone;时self.view会避开一切系统的bar,不会占满整个屏幕
  • 当self.edgesForExtendedLayout = UIRectEdgeAll;时,self.view会延伸到系统bar下面,占满整个屏幕,由于bar半透明可以隐约看到self.view或者其子视图的颜色透上来


self.navigationController.navigationBar.translucent = NO;(导航条不透明)时,self.view是否占满屏幕受到两个属性的影响:self.edgesForExtendedLayout和self.extendedLayoutIncludesOpaqueBars

  • 只有两个同时满足时才会占满整个屏幕(self.extendedLayoutIncludesOpaqueBars = YES && self.edgesForExtendedLayout = UIRectEdgeAll;)

至于
automaticallyAdjustsScrollViewInsets的目的是为了避免系统bar遮挡了要显示的view,所以设置为YES时也只在self.view延伸到bar下面的时候并且子视图里有滚动视图的时候才有用,系统可以把滚动视图contentInset某一个值设置为bar的高度一致(自行学习contentInset属性),相当于对滚动进行了填充避免被遮挡要显示的内容。

最后总结的不太好,请自行结合前文的说明理解。本文举例说的bar都是用的navigationBar,结合文档来看,这几个属性对于系统提供的tabbar等也有相同的效果。

老人新手,如有说的不对之处,万望指正!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容