通过自动布局在UIScrollView中使用顶层布局指南

我想通过自动布局使用UIScrollViewTop Layout Guide 。 如果没有UIScrollView自动布局可以很好地与Top Layout Guide在这里输入图像说明

但是,当我在UIScrollViewembeddedUIButton ,它不。 在这里输入图像说明

我知道这是因为UIScrollViewTop Layout Guide 。 但我认为可能有一个很好的解决scheme来解决这个问题。

你是对的混淆。 这有点违反直觉,但是顶部和底部的布局指南与configurationUIScrollView无关,因此它的可滚动内容将低于半透明的导航栏,这是您要实现的效果。

该怎么办

鉴于您在第二张图中显示的视图层次结构,您需要在iOS8上执行以下操作:

  1. configuration视图控制器,以便“在顶栏上延伸边缘”被选中(在代码中,使用edgesForExtendedLayout )。 这将确保视图控制器布局它的根视图,以便它下面的导航栏。

  2. configuration滚动视图约束,以便滚动视图的顶部边缘与其顶层视图的顶部边缘具有零偏移, 而不是顶部布局指南中的零空间。 这将确保收集视图填充根视图,并因此也低于导航栏,这是滚动视图的内容能够在导航栏下滚动所必需的。 (国际文凭组织可能会与你作斗争,请参阅下面的脚注。)

  3. 所以,现在你如何确保滚动视图有任何想法,哪里的导航栏,所以(举例来说)它并不总是其位于导航栏下的内容? 答案与布局指南无关。 在视图控制器中,选中“调整滚动视图插入”(或在代码中, automaticallyAdjustsScrollViewInsets调整滚动视图插入)。 这将导致视图控制器自动调整滚动视图的contentInset属性,以便滚动视图适当地定位其内容。

这将工作。

这是怎么回事

那为什么这个答案呢? 为什么这么混乱?

坦率地说,很容易混淆,因为顶部和底部的布局指南作为传达关于半透明叠加元素的布局信息的元素被显着地呈现给我们。 但是,它们并不是唯一的“半透明意识”的布局机制。 它们只与“正常”子视图的定位直接相关,即不是视图控制器的根视图,也不是UIScrollView中的内容。

滚动视图(或UICollectionView和UITableView之类的子类)中的内容将始终以涉及滚动视图本身的更复杂的方式进行定位,受诸如contentInsetcontentOffset等属性的影响。(真的,如果滚动视图布局是直截了当的事情,为什么苹果有专门的WWDC会议滚动过去四年的视图布局运行?!)

总而言之,正如以上步骤所表明的那样,pipe理布局的三种不同的半透明感知机制如下:

  1. Extends Edges确定视图控制器是否放置其根视图,以使其位于导航栏下方。

  2. 布局指南提供了一个度量标准,可以说明“主”内容区域的位置,并考虑到半透明条。 您可以将这些与自动布局一起使用来放置正常的视图,以避免重叠。 或者你可以在代码中访问数值。

  3. 滚动视图插图是确保滚动视图的内容可能不足但正常情况下不正确的正确方法。 视图控制器上的automaticallyAdjustsScrollViewInsets属性可以在简单情况下自动为您执行此操作。 (大概这个属性只是让视图控制器根据它通过布局指南公开的相同的值更新滚动视图的contentInset ,所以如果你自己需要pipe理这些insets的话,那你就是这么做的。

与IB的布局引导狂热战斗

关于“与IB战斗”的脚注:

不幸的是,当你尝试将滚动视图边限制到它的超视图的边缘时,界面生成器可能会对抗你。 如果您按住Ctrl键并从滚动视图拖到超级视图,那么当它popup可能的约束菜单以在这些视图之间添加时,它可能会尝试让您根据视图控制器的布局指南约束滚动视图。 这是因为当superview是根视图时,IB无意中更喜欢布局指南来超视图边缘。 但是当你使用scrollview时,这是错误的

为什么? 例如,假设您接受对布局指南的限制。 那么你将最终在你的滚动视图的顶部约束,约束到topLayoutGuide-64.0。 这是-64.0是一个硬编码值,以补偿导航栏的确切高度。 那么当一个好日子的导航栏不等于64pt时会发生什么? 或者当你完全closures导航栏? 或者想在没有导航栏的情况下重新使用这个场景? 答:那么你会得到一个破碎的布局。

那么如何强制IB将滚动视图添加到其超级视图的边界,而不是布局指南? 据我所知,答案是你不能在IB中正确添加该约束,通过在视图之间进行Ctrl-拖动。

相反,您需要select视图,然后使用canvas底部的“Pin”控件。 这是一个看起来像一个箱子在中间的首都H. 在Pinpopup对话框的顶部,小图显示超视图空间约束的部分,可以使用文本字段旁边的下拉控件来configuration空间约束是否绑定布局指南或超级视图。 如下所示:

Pin对话框,用于约束布局指南vs视图

Github链接到演示项目: https : //github.com/algal/ScrollViewUnderlapDemo

虽然algal的答案似乎在iOS 9.0之前起作用,但它不必要的复杂,并且超越了iOS 9.0。 在iOS 9.0之外的更简单的方法,不需要与自动布局进行交互,只需简单地执行以下操作:

  1. 确保Adjust Scroll View Insets在Interface Builder中被检查为ViewController(或者以编程方式automaticallyAdjustsScrollViewInsets设置为true )。
  2. 在Interface Builder中将ViewController的根View的类设置为UIScrollView (或者用代码中的UIScrollView手动replace它(self.view))。

在添加间隔约束的同时,Xcode不会显示与视图有距离的项目。 看来你在UIScrollViewUIView之间添加了一个垂直空间约束。 删除该约束,将您的滚动视图移动到Top Layout Guide 下方,并在UIScrollViewTop Layout Guide之间添加一个新的垂直空间约束。