将视图添加到将拉伸以填充可用宽度的滚动视图

Posted

技术标签:

【中文标题】将视图添加到将拉伸以填充可用宽度的滚动视图【英文标题】:Adding a view to a scroll view that will stretch to fill available width 【发布时间】:2015-02-01 22:36:35 【问题描述】:

我在情节提要中使用自动布局,没有代码,并且难以让滚动视图的内容视图中的视图拉伸以填充设备宽度。我知道这个问题是一个模棱两可的滚动视图宽度,但是当我希望它始终拉伸以填充可用宽度(带有一些填充)时,我不确定如何使它不模棱两可。

在视图控制器中,我添加了一个带有 4 个约束的滚动视图:顶部、底部、前导、尾随到超级视图。我向滚动视图添加了一个视图,它将充当内容视图 - 所有子视图都将添加到内容视图中。它有 4 个约束:顶部、底部、前导、尾随滚动视图。然后,我将我希望可见的视图(一个简单的红色框,它具有固定的高度但会拉伸以填充屏幕宽度)添加到内容视图中。它的约束是:拖到superview(15),到superview(15),top到superview(15),bottom到superview(15),高度等于60。

这会导致滚动视图宽度不明确,并且框架错位 - 它想将框视图的宽度设置为 0。

如何设置此框视图以填充设备屏幕,解决滚动视图内容大小宽度模糊问题?

【问题讨论】:

由于您为红色框添加到内容视图的 UIView 没有任何固有宽度,因此您会感到模棱两可。我的建议是为 UIView 的宽度添加一个新的约束,将其设置为任何值,但使其优先级低于其他约束。这应该有效。 @user3435374 这确实消除了歧义,但即使在降低了宽度约束优先级之后,它也将框固定为该尺寸集。 【参考方案1】:

ios 11 及更高版本中,滚动视图有两组布局指南,一组用于可滚动内容,contentLayoutGuide(指示滚动行为),另一组用于其框架,frameLayoutGuide(指示大小子视图)。

例如,这添加了一个子视图,它一直插入 20 个点,其宽度是相对于滚动视图的框架设置的,但具有固定的高度:

let subview = UIView()
subview.translatesAutoresizingMaskIntoConstraints = false
subview.backgroundColor = .red
scrollView.addSubview(subview)

NSLayoutConstraint.activate([
    subview.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor, constant: 20),
    subview.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor, constant: -20),
    subview.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor, constant: 20),
    subview.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor, constant: -20),

    subview.heightAnchor.constraint(equalToConstant: 1000),
    subview.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor, constant: -40),
])

您也可以在 IB 中执行此操作,完全无需任何编码:

在 iOS 11 之前,在没有 frameLayoutGuide 的情况下,您必须根据滚动视图的父视图设置子视图的约束,我将在下面概述该过程。但是从 iOS 11 开始,以上是更直观的解决方案。


您在问题中描述的约束等同于以下 VFL:

滚动视图占据整个视图

H:|[scrollView]|
V:|[scrollView]|

红色视图高 60 pt,与滚动视图的 contentSize 边缘有 15 的边距:

H:|-(15)-[redView]-(15)-|
V:|-(15)-[redView(60)]-(15)-|

红色视图是模棱两可的,因为没有定义它的宽度。 (红色视图和滚动视图之间的水平约束定义滚动视图的contentSize,而不是红色视图的宽度。参见Apple Technical Note 2154。)

您可以通过添加一个约束来解决这种歧义,即红色视图比主视图窄 30pt。因此,通过 control 在红色视图和滚动视图的超级视图之间添加约束 - 从红色视图拖动到滚动视图(这可能是从文档大纲中最容易做到的):

然后选择“等宽”:

已将红色视图定义为与主视图相同的宽度,您现在必须更改该约束以修改常量以调整您在红色视图和滚动视图的contentSize 之间提供的边距。因此,选择您刚刚添加的约束并对其进行编辑,将常量更改为 -30:

坦率地说,Interface Builder 技术有点麻烦。以编程方式说明如何执行此操作可能更容易:

view.addConstraint(NSLayoutConstraint(item: redView, attribute: .Width, relatedBy: .Equal, toItem: view, attribute: .Width, multiplier: 1.0, constant: -30))

【讨论】:

从来没有想过这个...非常聪明

以上是关于将视图添加到将拉伸以填充可用宽度的滚动视图的主要内容,如果未能解决你的问题,请参考以下文章

仅在自动布局中具有固定宽度的垂直滚动视图

为啥图像视图会拉伸以填充 UIStackView 中宽度的一半?

如何让 UICollectionView 在不离开屏幕的情况下使用自动布局填充其包含滚动视图的宽度?

将图像和滚动图标添加到表格视图的逻辑

即使内容大小较大,滚动视图也不会滚动

如何调整标签大小以适应任何屏幕尺寸