的开发者, 我在界面生成器(Xcode 5 / iOS 7)中的自动布局遇到了麻烦。 这是非常基础和重要的,所以我认为每个人都应该知道这是如何正确工作的。如果这是Xcode中的一个bug,那它就是一个严重的bug !

所以,每当我有这样的视图层次结构时,我就会遇到麻烦:

>UIViewController
>> UIView
>>>UIScrollView
>>>>UILabel (or any other comparable UIKit Element)

UIScrollView有固定的约束,例如,每边50px(没问题)。 然后我添加一个顶部空间约束UILabel(没有问题)(我甚至可以钉标签的高度/宽度,改变什么,但应该是不必要的,由于标签的内在大小)

当我给UILabel添加一个尾随约束时,问题就开始了:

例如,尾随空间到:Superview等于:25

现在出现了两个警告——我不明白为什么:

A)滚动内容大小不明确(滚动视图具有不明确的滚动内容高度/宽度)

B)视图错位(Label Expected: x= -67 Actual: x= 207)

我在一个新项目中做了这个最小的例子,你可以下载,我附上了一张截图。如你所见,Interface Builder期望Label位于UIScrollView的边界之外(橙色虚线矩形)。用解决问题工具更新标签的框架,将其移到那里。

请注意:如果你用一个UIView替换UIScrollView,行为是预期的(标签的帧是正确的,根据约束)。所以看起来要么是UIScrollView有问题,要么是我错过了一些重要的东西。

当我运行应用程序而不更新标签的框架时,它的位置很好,正是它应该在的地方,UIScrollView是可滚动的。 如果我确实更新了帧,标签就会从视野中消失,UIScrollView也不会滚动。

帮帮我,欧比王·克诺比!为什么是模棱两可的布局?为什么会出现这种错位的观点?

你可以在这里下载示例项目,试着看看你能弄清楚发生了什么: https://github.com/Wirsing84/AutoLayoutProblem


当前回答

我知道我可能晚了,但是下一个解决方案无需额外的代码就解决了这类问题,只是使用故事板:

对于你的内容视图,你需要设置前/后/上/下空格到滚动视图的约束,这不会改变内容视图框架,如下所示:

当然,您需要为内容视图创建额外的约束,以便滚动视图可以知道内容大小。例如,设置固定高度和中心x。

希望这能有所帮助。

其他回答

如果你仍然有UIScrollView的问题,只要关闭内容布局指南 (在xcode Interface Builder中选择你的ScrollView ->在右侧面板中选择尺寸检查器->取消选择“内容布局指南”) 或者试试这些步骤:xcode 11滚动视图布局-它可以 对新的版式很有用。适用于macOS 10.15.2, Xcode 11.3.1, 05.02.2020

看到截图

@Matteo Gobbi的答案是完美的,但在我的情况下,滚动视图不能滚动,我删除“对齐中心Y”,并添加“高度>=1”,滚动视图将成为可滚动的

[在XCode 7.2和iOS 9.2中测试]

对我来说,抑制Storyboard错误和警告的方法是将滚动视图和内容视图(在我的例子中,是一个stackview)的固有大小设置为Placeholder。这个设置可以在故事板的大小检查器中找到。它说-设置设计时间内在内容大小只影响在界面生成器中编辑时的视图。视图在运行时没有这个固有的内容大小。

所以,我想我们设置这个不会错。

注意:在storyboard中,我已经将scrollview的所有边固定在superview上,将stackview的所有边固定在scrollview上。在我的代码中,我已经为scrollview和stackview设置了translatesAutoresizingMaskIntoConstraints为false。我还没有提到内容大小。当堆栈视图动态增长时,在故事板中设置的约束确保堆栈是可滚动的。

故事板警告快把我逼疯了,我不想为了抑制警告而水平或垂直地将事物居中。

我知道我可能晚了,但是下一个解决方案无需额外的代码就解决了这类问题,只是使用故事板:

对于你的内容视图,你需要设置前/后/上/下空格到滚动视图的约束,这不会改变内容视图框架,如下所示:

当然,您需要为内容视图创建额外的约束,以便滚动视图可以知道内容大小。例如,设置固定高度和中心x。

希望这能有所帮助。

垂直滚动

添加一个带有约束0,0,0,0的UIScrollView到superview。 在ScrollView中添加一个UIView,约束为0,0,0,0到superview。 为UIScrollView添加相同宽度的约束。 添加高度到UIView。 向UIView添加带有约束的元素。 对于最靠近底部的元素,确保它有一个到UIView底部的约束。