Autolayout的Top Layout guide问题

iOS开发——Autolayout的Top Layout guide问题

写这篇博客以前,真想大吼一声:Top Layout Guide,你究竟是什么鬼!html

问题描述

在学习UIPageViewController的过程当中,按照《【译】如何使用Storyboard建立UIPageViewController》编写引导页Demo,可是作完的效果和Demo效果有一些出入,效果分别为:正确效果错误效果ide

简单说就是当滑动到下一页的时候,下一页会有一个缩小效果,可是这个效果并非手动添加的。布局

分析问题

以前的那篇《iOS学习笔记——UIScrollView的坑和填坑》中提到了Autolayout的问题:自动添加Constraints致使出错。此次要说的问题和上次都和一个东西有关——Top Layout Guide。学习

Top Layout Guide用于自动布局的辅助,在Storyboard中能够看到Top Layout Guide做为ViewController的属性存在,也就是topLayoutGuide,官方文档对这个属性的Discussion是:ui

topLayoutGuide属性表示不但愿被透明的状态栏或导航栏遮挡的内容范围的最高位置。这个属性的值是它的length属性的值(topLayoutGuide.length),这个值可能由当前的ViewController或这个ViewController所属的NavigationController或TabBarController决定,有以下状况:spa

  • 一个独立的ViewController,不包含于任何其余的ViewController。若是状态栏可见,topLayoutGuide表示状态栏的底部,不然表示这个ViewController的上边缘。htm

  • 包含于其余ViewController的ViewController不对这个属性起决定做用,而是由容器ViewController决定这个属性的含义:生命周期

    • 若是导航栏(Navigation Bar)可见,topLayoutGuide表示导航栏的底部。开发

    • 若是状态栏可见,topLayoutGuide表示状态栏的底部。文档

    • 若是都不可见,表示ViewController的上边缘。

这部分还比较好理解,总之是屏幕上方任何遮挡内容的栏的最底部。

经过对ViewController的生命周期消息进行跟踪,在下一页显示出来前,首先调用下一页ViewController的viewDidLoad方法,也就是加载过程,此时topLayoutGuide值为0;而显示的消息viewWillAppear:和布局的消息viewWillLayoutSubview在放开手指以后才会发送,而这个时候已经彻底显示了,topLayoutGuide的值为20,也就是在状态栏下边缘。

当松手的时候,topLayoutGuide的值发生的这一个变化,就致使咱们看到了一个忽然缩小的效果。

解决问题

到如今为止,找到了两个解决方法,不过并不完美。

方法一:在设置自动布局约束时,不使用Top Layout Guide,而是使用父View的上边缘。

说方法二以前,还要在说一下AutoLayout的设置,默认添加的约束是这样的:

屏幕快照 2014-10-22 下午3.48.30

注意第二项Top Layout Guide.Bottom,也就是约束到topLayoutGuide的下边缘,也就是说topLayoutGuide是有高度的!!

再次查文档中对length的解释:

The top layout guide indicates the distance, in points, between the top of a view controller’s view and the bottom of the bottommost bar that overlays the view.

能够看到是指当前ViewController的上边缘到遮挡内容的Bar的下边缘,那么topLayoutGuide的top和bottom也就是这两个边缘了。

方法二:自动布局的约束中,将Top Layout Guide.Bottom改成Top Layout Guide.Top。

这两个方法达到的效果是同样的,都是让Label之内容ViewController的上边缘进行约束,也就不会有变化了。Demo中没有这个问题,是由于Demo没有使用Autolayout。

可是也正是如此,两个方法都不完美。内容ViewController是动态加载并嵌入到UIPageViewController中的,而topLayoutGuide又是一个只读属性,不能嵌入到UIPageViewController以前进行设置。

完美的方法应该是在加载内容ViewController的同时,告知内容ViewController它将被嵌入到另外一个容器当中,而这个容器包含一个Status Bar,因此应该从新判断topLayoutGuide的值,但遗憾的是目前尚未找到这种完美的解决方案。若是你知道,但愿能告诉我,谢谢!

相关文章
相关标签/搜索