在滚动视图中使用堆栈视图并尊重安全区域插图

Using a Stack View in a Scroll View and respecting Safe Area insets

我在垂直滚动 UIScrollView 中有一个 UIStackView,所有内容都使用自动布局进行限制。滚动视图填充父视图,堆栈视图填充滚动视图,各种元素被添加到堆栈视图中。为了让它与自动布局一起很好地发挥作用并定义滚动视图的内容大小,您还必须指定堆栈视图的宽度。这是通过在堆栈视图上添加宽度约束来完成的,等于滚动视图的宽度。在这一点上没有什么是模棱两可的,它的行为完全符合要求。

现在,如果您想添加边距以使元素不会拉伸到屏幕的最左边缘和最右边缘,您可以将堆栈视图上的前导和尾随约束常量更改为在两者上都插入 15pt双方例如。但是你必须确保将等宽约束常数更改为-30。这很有效,插入了可滚动的内容,仍然允许您在屏幕的远端滑动以滚动。

现在,iPhone X 出现了,横向时 15pt 的填充不再足够,因为内容被放置在外壳传感器下方。因此,您需要更新它以设置边距以遵守安全区域布局边距。您真的只想使用默认边距。您可以更改堆栈视图的前导和尾随约束常量以使用视图的布局边距(尊重安全区域插图),但这将不起作用,因为您的等宽约束常量不再是边距量的两倍,边距是动态的现在。

因此,解决此问题的一种方法是为堆栈视图的前导和尾随以及宽度约束创建 IBOutlet,然后在布局边距发生变化时以编程方式调整它们 (viewLayoutMarginsDidChange)。但我想知道是否有更好的方法,最好是在 Interface Builder 中工作的解决方案,不需要代码。

我找到了一种完全在 Interface Builder 中完成此操作的方法。不是直接在滚动视图中嵌入堆栈视图,而是在滚动视图中添加一个 UIView 作为内容视图。创建 leading、trailing、top 和 bottom 约束都等于 superview 的常量为 0,加上滚动视图的等宽约束。然后将堆栈视图嵌入到这个内容视图中。为堆栈视图创建前导和尾随约束等于父视图的 margin¹,加上顶部和底部。

因此您的设置将是:

- view
-- scroll view
--- view
---- stack view

这将确保在横向 iPhone X 上您可以在左右边缘滚动,滚动条位于屏幕的最右边缘,堆栈视图位于安全范围内面积

¹ 我发现常量 8 增加了足够的填充,让人感觉不错。

纯界面构建器解决方案(比公认的更好):

  1. UIScrollView 下面添加一个虚拟 UIView (下面,因为 滚动视图的自动内容插入工作)
  2. 设置view的高度为0px,leading和trailing为 superview 的前导和尾随 有边距 ! (对边距很重要)
  3. 从堆栈视图(这是 滚动视图的内容视图)到虚拟视图,并更改堆栈视图的前导和尾随以尊重边距
    1. 设置在滚动视图上保留边距

完成