通过自动布局使用UIScrollView中的顶部布局指南

时间:2014-05-07 04:51:12

标签: ios uiscrollview interface-builder autolayout

我想通过自动布局使用Top Layout Guide中的UIScrollView。没有UIScrollView自动布局与Top Layout Guide配合良好。 enter image description here

但是当我将UIButton嵌入UIScrollView时,它却没有。 enter image description here

我知道这是因为UIScrollViewTop Layout Guide的层次结构级别不同。但我认为可能有一个很好的解决方案来解决这个问题。

3 个答案:

答案 0 :(得分:18)

你很困惑。这有点违反直觉,但顶部和底部布局指南与配置UIScrollView 无关,因此其可滚动内容将覆盖半透明导航栏,这是您尝试实现的效果。

该怎么做

鉴于您在第二张图片中显示的视图层次结构,这是您在iOS8上需要做的事情:

  1. 配置视图控制器,以便"在顶栏下扩展边缘"已选中(在代码中,使用edgesForExtendedLayout)。这将确保视图控制器布置其根视图,以便它在导航栏下方。

  2. 配置滚动视图约束,以使滚动视图的上边缘与其超视图的上边缘的偏移量为零,从顶部布局指南中的零空间。这将确保集合视图填充根视图,从而也使导航栏重叠,这对于滚动视图的内容能够在导航栏下滚动是必要的。 (IB可能会打击你。请参阅下面的脚注。)

  3. 那么现在如何确保滚动视图知道导航栏的位置,以便(例如)它不会总是将其内容置于其下导航栏?答案与布局指南无关。在视图控制器中,选中框"调整滚动视图插图" (或代码中,automaticallyAdjustsScrollViewInsets)。这将导致视图控制器自动调整滚动视图的contentInset属性,以便滚动视图适当地定位其内容。

  4. 这样可行。

    正在进行什么

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

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

    滚动视图(或UICollectionView和UITableView等子类)中的内容将始终以更复杂的方式定位,包括滚动视图本身,受contentInsetcontentOffset等属性的影响..(实际上,如果滚动视图布局很简单,为什么Apple会在过去四年中有专门的WWDC会话来滚动视图布局?!)

    总而言之,正如上面的步骤所示,用于管理布局的三个不同的半透明感知机制如下:

    1. 扩展边缘确定视图控制器是否定位其根视图以使其位于导航栏下方。

    2. 布局指南提供了一个指标,用于说明" main"内容区域,考虑半透明条。您可以将这些与自动布局一起使用来定位普通视图,以便它们不会重叠。或者您可以访问代码中的数值。

    3. 滚动视图插播是确保滚动视图内容可以重叠但不会始终不足的正确方法。视图控制器上的automaticallyAdjustsScrollViewInsets属性可以在简单的情况下自动执行此操作。 (据推测,此属性只会使视图控制器根据它通过布局指南公开的相同值更新滚动视图contentInset。因此,如果您需要自己管理插图,那么'你将如何做到这一点。)

    4. 打击IB的布局指南狂热

      "与IB战斗的脚注":

      不幸的是,当您尝试将滚动视图边缘约束到其superview的边缘时,Interface Builder可能会对您不利。如果从滚动视图到超级视图进行按住Ctrl键拖动,当它弹出可能的约束菜单以在这些视图之间添加时,它可能会尝试让您根据视图控制器的布局约束滚动视图指南。这是因为当superview是根视图时,IB盲目地更喜欢布局指南到superview边缘。但是当你使用滚动视图时,这是错误的

      为什么呢?例如,假设您接受布局指南的约束。然后,您将在滚动视图上最终得到一个顶级约束,将其限制为topLayoutGuide-64.0。 -64.0是一个硬编码值,用于补偿导航栏的精确高度。那么当一个晴天导航栏不等于64pt时会发生什么?或者当您完全关闭导航栏时?或者想在没有导航栏的情况下重新使用此场景?答:然后你得到一个破碎的布局。

      那么如何强制IB从滚动视图向其superview的边缘添加约束,而不是布局指南?据我所知,答案是你不能通过在视图之间进行ctrl-drag来正确地在IB中添加该约束。

      相反,您需要选择视图,然后使用" Pin"控件在画布的底部。这是一个看起来像大都市H的中间有一个方框。在“引脚”弹出对话框的顶部,显示超视图空间约束的小图的部分,您可以使用文本字段旁边的下拉控件来配置空间约束是否绑定布局指南或超级视图。如下所示:

      Pin dialog, for constraining layout guides vs view

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

答案 1 :(得分:1)

尽管藻类的答案似乎在iOS 9.0之前有效,但它不必要地复杂并且超越了iOS 9.0。更简单的方法也可以在iOS 9.0之外工作,并且不需要与自动布局交互,只需执行以下操作:

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

答案 2 :(得分:0)

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