如何使用 Autolayout 在我的 UIScrollview 上设置约束?

Posted

技术标签:

【中文标题】如何使用 Autolayout 在我的 UIScrollview 上设置约束?【英文标题】:How can I use Autolayout to set constraints on my UIScrollview? 【发布时间】:2013-12-11 22:43:35 【问题描述】:

我花了两天时间尝试了Mixed and Pure Autolayout approaches 的各种解决方案,以实现在自动布局之前简单的滚动视图设置,现在它是官方的 - 我一定是太愚蠢了。我主要在 Storyboard 中进行设置(嗯,就是这样)。

所以这是我的求助请求。

视图树:

UIView
-UIView
-UIView
..-UIScrollview
...-UIButton
...-UIButton
...-UIButton

按钮应该水平滚动(从左到右,反之亦然)。有人可以让我知道如何设置约束以使用纯自动布局来实现这一目标???

--

我尝试过混合方法,如下所示:

UIView
- UIView
- UIView
..-UIScrollview
...-UIView (contentview)
....-UIButton
....-UIButton
....-UIButton

...并根据 Apple 的技术说明为 contentviewtranslatesAutoresizingMaskIntoConstraints 设置设置固定的宽度和高度限制。按钮和滚动视图是使用约束设置的。这让滚动视图滚动(耶),但是,它滚动得太远了!据我所知,滚动宽度比我设置的内容视图翻了一番???!!!???

我也尝试了纯自动布局方法,有contentview 和没有。 所有视图均为translatesAutoresizingMaskIntoConstraints=NOself.view 除外。按钮具有固定的宽度/高度约束,并固定到滚动视图的所有四个边缘。没有滚动。

所以我完全困惑为什么我不能让它正常工作。非常感谢任何帮助,如果您需要任何其他信息,请询问!

更新的屏幕截图和解决方案 - buttonZ 约束:

编辑@杰米福雷斯特 所以解决方案原来是最后一个按钮上的错误尾随约束。我设置的值不是 6441,而是负数,-6441。棘手的是,在 Storyboard 中设置值时,Pin 工具栏中有两个选项:

当前画布值为负(导致不滚动),下面的选项为正(激活滚动)。这意味着我并不愚蠢,但我猜至少是半盲的。 虽然,在我看来,XCode 没有显示“不正确”设置的错误,这不是有点令人不安吗?

再次编辑 现在这很有趣......将尾随值从 -6441(无滚动)更改为 6441 启用滚动。但是我的老朋友“太多内容大小”又回来了,导致内容大小是应有大小的两倍!获得正确内容滚动的解决方案是将尾随约束设置为零!这在 Storyboard 中工作时并不明显,但在查看 @Infinity James 的代码时,它应该是这样的。

【问题讨论】:

您在哪里计算/设置滚动视图的内容大小?提到您第一次尝试使用 contentView 时,您说它滚动得太远了。 据我所知,您不能仅使用自动布局设置UIScrollViewcontentSizecontentSize 定义了您可以滚动多少。所以你最终必须在某个地方手动设置它。其余的,您可以使用布局约束来设置彼此相对的视图框架。 @Jeff,内容大小是固定的,永远不会改变。我通过手动为 contentiview 输入正确的高度和宽度来设置情节提要中的内容大小,并在情节提要中使用约束固定高度和宽度。 在运行时打印出你的 contentSize,看看它是否与你输入的值匹配。 contentSize 决定发生多少滚动,因此您第一次尝试的问题与 contentSize 有关。 @Guillaume,所以“纯粹的自动布局”方法毕竟不是那么纯粹吗?但是如何手动设置 contentSize?正如我上面提到的,我将内容视图的高度/宽度设置为固定值(在情节提要中)。但它滚动得太远(2x)。 【参考方案1】:

当您将它们粘贴到此处时,很难看到您的约束的确切值和设置,所以通过查看您的屏幕截图我不确定您哪里出错了。

我创建了一个基本的sample project,而不是解释您的设置有什么问题,其视图层次结构和约束设置与您描述的非常相似。水平滚动在示例项目中按预期工作,它使用 Apple 在Technical Note 中描述的“Pure AutoLayout”方法。

最初让 Auto Layout 与 UIScrollView 一起工作时,我也遇到了很多麻烦。让它工作的关键是确保滚动视图中的所有项目加在一起,具有最终链接到滚动视图所有方面的约束,并有助于 AutoLayout 系统能够确定 contentSize 为滚动视图将大于其框架。看起来您正在尝试在代码中执行此操作,但可能您有一些多余的约束导致 contentSize 太小。

另外值得注意的是,正如其他人提到的,使用 AutoLayout 和 UIScrollview,您不再显式设置 contentSize。 AutoLayout System 根据您的约束计算 contentSize。

我还发现this ebook chapter 非常有助于让我了解这一切是如何运作的。希望这对您有所帮助。

【讨论】:

感谢您的示例项目!它有效,并且在查看它时,我一开始找不到我的项目有什么不同!我将视图复制到我的项目中,怀疑是约束之外的其他设置,但它继续工作。这让我注意到我项目中最后一个按钮的尾随约束有一个负值 - 在它前面,而你的有一个正值!将 - 更改为正启用滚动!当我打开 Pin 工具栏时,有两个选择:Use Current Canvas value,这是负数,以及 Scroll View(使用当前值),这是正数......?! 啊,是的。负值实际上会使滚动视图的 contentSize 更小,以匹配后沿应该在按钮结束之前结束 before 的事实。很高兴示例项目有所帮助! 它做了很多。查看我更新的答案。尾随值实际上应该是 0(零)。 我们不得不分享屏幕截图而不是代码,这很可悲。那只是因为苹果鼓励开发者使用builder而不是提供更好的api。 完全不直观。开发人员必须花费大量时间来弄清楚 XCode 的创作者的想法。【参考方案2】:

欢迎来到愚蠢俱乐部。我是创始人之一。 :D

对于垂直滚动:我可以让它工作的唯一方法(ios 8、Xcode 6 和纯自动布局)是将以下约束添加到我的滚动视图(都与超级视图相关):

等宽 等高 中心 Y 对齐 中心 X 对齐

我的结构:

  UIView
   - ScrollView
    - Subview
    - Subview
    - Subview
    - Subview
    - ...

这是最终结果:

这是设置:

Full screen

And here is the project.

希望这可以避免有人在凌晨 5 点睡觉。 :D

【讨论】:

非常感谢您的帮助!您是如何获得“子视图”类型的子视图的?我正在查看您在 Xcode 6.2 中的项目,它将那些小矩形称为“子视图”,唯一的限制是它的高度为 63 像素。 您好!那个“子视图”实际上是一个 UIVIew。那只是一个名字……你可以在那里输入任何东西。查看这张图片:cl.ly/image/291f1K2N0V3p 在约束主题上,子视图不仅仅是高度约束。在此处检查这些视图的整个约束列表:cl.ly/image/3l061i123j2i 我仍然无法进行滚动工作——我注意到您的子视图视图在您的项目中“变灰”。在做了一些研究之后,看起来这是因为您使用的是“大小类”。这对滚动有何影响?有没有办法在不使用它的情况下让滚动工作? 另外,你是如何让你的超级视图比默认长度长这么多的?我正在尝试添加将出现在“折叠下方”(或屏幕外)的按钮,但显然如果我无法将它们拖放到超级视图中,因为它不够大,我无法将它们添加到超级视图中。 经过一整天的搜索和尝试做这种愚蠢的布局后,我找到了这个答案并在第一次尝试时就工作了。谢谢伙计..你救了我的一天..我希望我能给一千为这个答案投票.. :)【参考方案3】:

简单的独立示例

从对问题的高票数和对答案的低票数来看,人们在这里找不到可理解且快速的解决方案。让我尝试添加一个。这个项目是一个完全在 Interface Builder 中完成的独立示例。您应该能够在 10 分钟或更短的时间内完成它。然后,您可以将学到的概念应用到您自己的项目中。

最初的问题是关于滚动按钮的。这里我只使用UIViews,但它们可以代表你喜欢的任何视图。我还选择了水平滚动,因为这种格式的情节提要屏幕截图更紧凑。不过,垂直滚动的原理是相同的。

关键概念

UIScrollView 应该只使用一个子视图。这是一个“UIView”,用作内容视图来保存您希望滚动的所有内容。 使内容视图和滚动视图的父视图具有相同的高度以进行水平滚动。 (垂直滚动的宽度相等) 确保所有可滚动内容都具有设定的宽度并固定在所有侧面。

开始一个新项目

它可以只是一个单一的视图应用程序。

故事板

在这个例子中,我们将制作一个水平滚动视图。选择 View Controller,然后在 Size Inspector 中选择 Freeform。设置宽度1,000 和高度300。这只是为我们在情节提要上提供了空间来添加将滚动的内容。

添加滚动视图

添加UIScrollView 并将所有四个边固定到视图控制器的根视图。

添加内容视图

UIView 作为子视图添加到滚动视图。 这是关键。 不要尝试在滚动视图中添加大量子视图。只需添加一个UIView。这将是您要滚动的其他视图的内容视图。将内容视图固定到所有四个侧面的滚动视图。

等高

现在在文档大纲中,Command 同时单击内容视图和滚动视图的父视图,以便同时选择它们。然后将高度设置为相等(Control 从 Content View 拖动到 Scroll View)。 这也是关键。因为我们是水平滚动,所以除非我们这样设置,否则滚动视图的内容视图不会知道它应该有多高。

注意:

如果我们让内容垂直滚动,那么我们会将内容视图的宽度设置为等于滚动视图的父视图的宽度。

添加内容

添加三个UIViews 并给它们所有约束。我对所有内容都使用了 8 点边距。

约束:

绿色视图:固定顶部、左侧和底部边缘。将宽度设为 400。 红色视图:固定顶部、左侧和底部边缘。将宽度设为 300。 紫色视图:固定所有四个边缘。使宽度与剩余空间无关(在本例中为 268)。

设置宽度约束也是关键,这样滚动视图才能知道其内容视图的宽度。

完成

就是这样。您现在可以运行您的项目。它的行为应该类似于此答案顶部的滚动图像。

对于垂直滚动,只需交换此示例中的所有宽度和高度方向(已测试且有效)。

进一步研究

iOS: How To Make AutoLayout Work On A ScrollView How to configure a UIScrollView with Auto Layout in Interface Builder YouTube视频教程:UIScrollView - How to keep your views on screen

【讨论】:

【参考方案4】:

contentSize 是通过在 UIScrollView 内部应用约束来隐式设置的。

例如,您是否在 UIView 中有一个 UIScrollView,它看起来像这样(我相信您知道):

    UIView *containerView               = [[UIView alloc] init];
    UIScrollView *scrollView            = [[UIScrollView alloc] init];
    [containerView addSubview:scrollView];
    containerView.translatesAutoresizingMaskIntoConstraints = NO;
    scrollView.translatesAutoresizingMaskIntoConstraints    = NO;
    NSDictionary *viewsDictionary       = NSDictionaryOfVariableBindings(containerView, scrollView);

    [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|"
                                                                          options:kNilOptions
                                                                          metrics:nil
                                                                            views:viewsDictionary]];
    [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|"
                                                                          options:kNilOptions
                                                                          metrics:nil

这会将滚动视图设置为填充容器视图的大小(因此容器视图必须具有一定的大小)。

然后,您可以通过将 UIScrollView 的 contentSize 隐式设置为足够大以容纳按钮,如下所示:

    UIButton *buttonA                   = [[UIButton alloc] init];
    UIButton *buttonB                   = [[UIButton alloc] init];
    UIButton *buttonC                   = [[UIButton alloc] init];
    [scrollView addSubview:buttonA];
    [scrollView addSubview:buttonB];
    [scrollView addSubview:buttonC];
    buttonA.translatesAutoresizingMaskIntoConstraints       = NO;
    buttonB.translatesAutoresizingMaskIntoConstraints       = NO;
    buttonC.translatesAutoresizingMaskIntoConstraints       = NO;

    viewsDictionary                     = NSDictionaryOfVariableBindings(scrollView, buttonA, buttonB, buttonC);

    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[buttonA]-|"
                                                                       options:kNilOptions
                                                                       metrics:nil
                                                                         views:viewsDictionary]];
    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[buttonA]-[buttonB]-[buttonC]-|"
                                                                       options:NSLayoutFormatAlignAllBaseline
                                                                       metrics:nil
                                                                         views:viewsDictionary]];

【讨论】:

那么,我设置了scrollView 和按钮之间的约束,而不是containerView 和按钮之间的约束?我认为这是我在你的代码和我现在通过故事板所做的事情之间的唯一区别。 我在第二次阅读后才意识到您正在设置 CONTAINERview 而不是 CONTENTview。根据您的代码,我已经完全在情节提要中重新创建了所有内容,并且没有滚动。我会用一些截图来编辑我的问题。 所以事实证明,我在情节提要中重新创建代码的尝试并不是 100% 正确的。最后一个按钮的尾随值应该完全为零,镜像 H:|-[buttonA]-[buttonB]-[buttonC]-|这在故事板中工作时并不是很明显(或者至少对我来说不是),但现在事实似乎微不足道。我喜欢自动布局,但那些小东西会让你... @user1459524 提到的对我来说是个问题。我的底部视图是一个按钮,底部约束是 IB 的 -32。我将其设置为 0 并在 IB 中更新为底部空间为:superview。它会起作用,而且似乎只要你站在积极的一面,它就会起作用。看起来这可能是 IB 的一个错误。希望对其他人有所帮助。我还删除了所有视图并重新布线,这有助于我发现它们在尝试布置这些视图时通常不会花费很长时间。【参考方案5】:

在 UIScrollView 中使用 AutoLayout 有很多问题,我们忽略的关键点是 UIScrollView 的内部视图对 Content View 而不是 UIScrollView 本身进行约束。参考Technical Note TN2154,可以找到:

UIScrollView 类通过更改其边界的原点来滚动其内容。为了使用自动布局,滚动视图中的顶部、左侧、底部和右侧边缘现在意味着其内容视图的边缘。

下图将描述:

你可以发现尾随空间是500点,如果对UIScrollView进行约束,视图将被错过放置,应该更新它的框架。但是,没有警告也没有错误。因为所有的约束都是针对内容视图的。

UIScrollView 会根据内部视图的约束来计算内容视图的大小。 (例如,内容大小:width = 100(前导空格)+ 200(视图宽度)+ 500(尾随空格),height = 131(顶部间距)+ 200(高度)+ 269(底部间距)

如何在 UIScrollView 中为视图添加约束:

    在内容视图中对视图的位置进行成像。 为内容视图的边缘添加上、右、下、左间距,此外,还添加这些视图的宽度和高度。

一切都完成了。

使用滚动视图处理 AutoLayout 的一种简单方法是在滚动视图中添加一个包含所有子视图的容器视图。

结论:理解带有 UIScrollView 的 AutoLayout 的关键是内部视图对内容视图而不是 UIScrollView 本身进行约束。

附example code

【讨论】:

【参考方案6】:

以下解决方案适用于 scrollView with autolayout and without contentSize

    将滚动视图拖放到 viewController 并应用任何约束来覆盖所需的空间。 在scrollView中拖拽一个UIView,使其覆盖scrollView的整个空间,并从scrollView应用上下左右空间约束。 根据滚动需要设置内视图的高度(如果需要水平滚动,则设置宽度)。如果需要,这部分也可以通过代码完成。 严重。在点 (3) 中将高度设置为某个较大的值后,返回点 (2) 并确保将顶部、左侧、右侧、底部的值设置为 回到零,因为 Xcode 可能有当您在 (3) 中强制更改高度时,为您更改了它们。

你就完成了。现在,您可以在此视图上添加任意数量的控件并应用彼此相关的约束(如果没有此视图,这些约束似乎不起作用)。如果您不想使用此视图,则必须为与 scrollView 相关的每个控件(彼此不相关)应用约束。


压倒性的提示........

严重。为了清楚起见,假设 UIScrollView 是 1000 宽 和 100 高。 (事实上​​,这些值通常是动态的,当然,取决于设备的宽度等。但现在只说 1000 宽和 100 高。)假设你正在做一个水平滚动。所以在 UIScrollView 里面放一个 UIView。 (即“内容视图”。)将内容视图顶部、底部、前导、尾随的所有四个约束设置为滚动视图。 即使看起来不对,也将它们全部设为零。 将内容 UIView 的高度设置为 100,然后忘记这一点。现在:您想水平滚动,所以将内容视图的宽度设置为 1225。

请注意,内容视图的宽度现在比父滚动视图的宽度大 225。没关系:事实上,你必须这样做。请注意

...你做 NOT 将尾随宽度设置为负 225...

您会认为您必须像平常一样“匹配”宽度。但如果你这样做,它根本不起作用。

您必须将前导和尾随数字设置为,绝不是负数(即使宽度“更大”)

有趣的是,您实际上可以将前导/尾随数字设置为任何 值(试试说“50”),它会为您提供某种反弹余量。 (它通常看起来很棒:试试吧。)任何一端的任何负值都会“默默地中断”。

请注意,令人恼火的是,通常是 Xcode(无论如何,从 7.3.1 开始),

将“有帮助”将这些值设置为负数!

因为它会尝试自动为您计算它们。如果是这样,它将无声地破裂。在第一个实例中将所有四个值都设置为零。并将内容视图的宽度设置为比示例中的“1000”宽得多。


已编辑: 我最终使用 UITableView 而不是 UIScrollView 来满足我的大部分需求。因为 tableView 在我看来更加灵活和动态。

【讨论】:

这实际上是这里最好的答案。谢谢!【参考方案7】:

我假设您遇到了contentSize 的问题。查看this blog post,了解在使用“纯”自动布局方法时如何处理contentSize。它的要点是您的约束隐含地定义了内容大小。使用 AutoLayout 时,您从不明确设置它。我在博文末尾附上了示例项目来演示它是如何工作的

【讨论】:

【参考方案8】:

技术说明中有一段您可能已经看过。您可以使用固定在滚动视图边缘的约束来隐式设置滚动视图的内容大小。

这是一个简单的例子。创建一个具有一个视图的故事板,该视图具有一个滚动视图。设置滚动视图约束,使其适合您放入的视图的大小。

在该滚动视图中添加一个视图。使用约束显式设置该视图的大小(并确保该大小大于滚动视图)。

现在向该内部视图添加四个约束,将内部视图的四个边缘锁定到其父滚动视图。这四个约束将导致内容大小扩大以适应内部视图。

如果您有多个视图要添加到滚动视图中,例如水平布局,您可以将第一个子视图的左侧锁定到滚动视图的左侧,将子视图水平锁定到彼此,最后一个子视图的右侧到滚动视图的右侧。这些约束将强制滚动视图的内容大小扩展以适应所有子视图及其约束。

【讨论】:

【参考方案9】:

如果您的问题是“我如何将一堆 UITextFields 放在垂直滚动的 UIScrollView 中,以便它们在获得焦点时移出键盘”,最好的答案是:

不要。

改为使用带有静态单元格的 UITableViewController。

如果您的视图控制器显示在 UINavigationController 中,则您可以免费获得这种滚动方式的行为,并且所有内容插入 Just Work。

【讨论】:

【参考方案10】:

你应该像这样组织你的布局ViewControllerView包含ScrollViewScrollView包含ContainerViewContainerView包含2个Labels

然后按照3个步骤让你的ScrollView可以滚动

    ScrollView 引脚(上/右/下/左)设置为ViewControllerViewContainerView 引脚(上/右/下/左)设置为ScrollView 设置Horizontally in Container不要设置Vertically in ContainerLabel1 销(顶部/右/左)到ContainerView Label1 pin(右/左/底部)到ContainerView顶部Label1

HERE is the demo project

希望有帮助

【讨论】:

【参考方案11】:

纯自动布局方法效果很好,但如果您从非自动布局迁移,设置起来会很痛苦。我已经做过几次了,我有一些一般性的提示:

从小处着手:即使这意味着重新创建情节提要视图,也可以从几个元素开始,然后慢慢构建视图,确保在添加一些元素后测试滚动是否有效。 关闭所有内容的 translatesAutoresizingMaskIntoConstraints:这一直是我的约束冲突的原因。 正确设置您的 UIScrollView 约束:确保滚动视图在所有方面都连接到父视图,否则它根本不会展开。

【讨论】:

【参考方案12】:

在处理这个问题一段时间后,我终于找到了解决方案。我正在使用通用班级大小的故事板(600x600)。我创建了一个滚动视图大小的 UIView (contentView),并为滚动视图创建了顶部、底部、前导和尾随的约束。然后我手动将 contentView 的大小裁剪为 600x600。故事板停止尝试调整所有内容,我可以工作,但在真实设备或模拟器上的视图看起来很糟糕。 我制作了 2 个这种剪裁尺寸的约束插座。

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *contentViewWidthConstraint; 
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *contentViewHeightConstraint;

然后在viewDidLoad中

CGSize viewSize = self.view.frame.size;
self.contentViewWidthConstraint.constant = viewSize.width;
self.contentViewHeightConstraint.constant = viewSize.height;

效果很好。

【讨论】:

【参考方案13】:

我花了几天的时间试图找到一个解决方案,如何使用 AutoLayout 视图和嵌入式 Scrollview,使滚动视图在可见屏幕中居中,适用于所有设备/屏幕尺寸以及屏幕旋转。

我花了几天时间尝试仅使用 Autolayout 来做到这一点,并且接近但还不够接近。所以最后我不得不在 viewDidLoad 中为每个屏幕添加 3 行代码。

请参阅下面的解决方案:

    创建滚动视图并用你想要的任何对象填充它 开启自动布局 然后将 ScrollView 垂直和水平居中 选择视图,然后选择'添加缺少的约束' - 这样就可以了 结果是生成了很多约束。为视图创建了 2 个新视图:“Horiz space scrollview to View”和“Vert space scrollview to view”,反之亦然。 删除“Horiz space scrollview to View”,因此您现在在 View 上剩下 3 个约束。 2 用于在视图中进入滚动视图,1 用于在滚动视图和视图之间设置垂直空间 现在将 Vert 约束链接到您的代码,方法是单击并按住 Ctrl 将其拖动到头文件并创建一个 NSLayoutConstraint IBOutlet(我叫我的 constraintVertVtoSV)

    现在转到 .m 文件并将这些代码行添加到 viewDidLoad 中(使用填充量来获得正确的垂直居中)

    if (IPAD)
    

    self.constraintVertVtoSV.constant = 150.0;

    现在应该可以在所有设备上运行,并且可以正确居中并且仍然可以正常滚动。

【讨论】:

【参考方案14】:

如果你像我一样在子视图中使用没有约束的静态内容,你可以这样做:

override func viewDidLayoutSubviews() 
    scrollView.contentSize = CGSizeMake(320, 800)

【讨论】:

【参考方案15】:

我今天在 iOS 8.4、Xcode 6.4 上遇到了类似的问题

有一个包含滚动视图的视图,包含一个包含子视图的内容视图(UIView)。

到处都是自动布局。 滚动视图边缘被固定到具有约束的父视图边缘。 内容视图边缘通过约束固定到滚动视图边缘。

最初内容视图会拒绝调整为滚动视图的整个宽度。我必须在内容视图上添加一个额外的约束,使其宽度与父滚动视图相匹配。或者我可以设置一个 contentView.centerX == scrollView.centerX 约束。除了固定边缘之外,其中任何一个都突然使内容视图的大小正确。

// Either one of these additional constraints are required to get autolayout to correctly layout the contentView. Otherwise contentView size is its minimum required size
scrollView.addConstraint(NSLayoutConstraint(item: contentView, attribute: .CenterX, relatedBy: .Equal, toItem: scrollView, attribute: .CenterX, multiplier: 1.0, constant: 0))
scrollView.addConstraint(NSLayoutConstraint(item: contentView, attribute: NSLayoutAttribute.Width, relatedBy: .Equal, toItem: scrollView, attribute: .Width, multiplier: 1.0, constant: 0.0))

使用表单的视觉约束将内容视图的边缘固定到滚动视图,

let cvConstraints = ["H:|[contentView]|", "V:|[contentView]|"]

我使用例程遍历数组并将它们添加到滚动视图。

【讨论】:

【参考方案16】:

我遇到了类似的问题。我设置了每一个约束并且总是想知道为什么它仍然调整一些子视图的大小。我的解决方案是将 clipsToBounds 设置为 YES。

【讨论】:

【参考方案17】:

swift 中,您可以使用这个有效的解决方案。

约束

ScrollView:领先、尾随、顶部、底部 = 超级视图

ContentView:前导、尾随、顶部、底部 = ScrollView。高度固定/相对于内容。

您可以将宽度约束(contentView)设置为等于滚动视图超级视图,但在构建时选择删除删除,因为您将以编程方式添加该约束。这只是为了让 IB 不会抱怨警告。

extension UIView 

    func setupContentViewForViewWithScroll(contentView vwContent : UIView) 
        //Set constraint for scrollview content
        let constraint = NSLayoutConstraint(item: vwContent, attribute: NSLayoutAttribute.Width, relatedBy: .Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: self.bounds.size.width)
        vwContent.addConstraint(constraint)
        self.layoutSubviews()
    


在 View Controller viewDidLayoutSubviews 我只是调用这个方法:

override func viewDidLayoutSubviews() 
    super.viewDidLayoutSubviews()
    self.view.setupContentViewForViewWithScroll(contentView: vwContent)

【讨论】:

【参考方案18】:

我知道这是一个外行的解决方案,而不是 Apple 在文档中建议的解决方案,但它对我有用两次,内容不同,并且可以非常快速地设置: 在故事板视图控制器中插入 UIView。 在 UIView 中插入 Table View、Dynamic、0 Prototype 单元格、Style Plain 或 Grouped。 在表视图中插入一个滚动视图, 在滚动视图中插入内容。 就是这样,自定义视图控制器中没有设置。

【讨论】:

以上是关于如何使用 Autolayout 在我的 UIScrollview 上设置约束?的主要内容,如果未能解决你的问题,请参考以下文章

给定具有多行标签的集合视图单元格的宽度,如何获得首选的 AutoLayout 高度?

Autolayout中的相对中心

如何使用 AutoLayout 使我的 UIImage 的高度与我的 UILabel 的固有高度相同?

自动布局:窗口调整大小时如何更改框架的原点?

如何使用 Autolayout 调整我的超级视图大小以匹配其子视图的大小?

使用 AutoLayout 缩小 UIImageView 高度