的开发者, 我在界面生成器(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


当前回答

使用contentView (UView)作为容器在UIScrollView,坚持边缘(上,下,后,前)的superview (UIScrollView)和contentView应该有等宽和等高的superview。这些都是约束条件。方法的调用:

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    self.scrollView.contentSize = self.contentView.frame.size;
}

为我解决了问题。

其他回答

对我来说,添加contentView并没有像建议的那样真正起作用。此外,由于添加了视图,它会产生开销(尽管我不认为这是一个大问题)。对我来说最有效的方法是关闭我的scrollView的歧义检查。一切都布置得很好,所以我认为在像我这样简单的情况下是可以的。但是请记住,如果你的scrollView的其他约束被打破,Interface-Builder将不再就此警告你。

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

看到截图

Swift 4+方法:

1)设置UIScrollView的上、下、左、右边缘为0

2)在UIScrollView中添加一个UIView,并设置顶部、底部、前边距和尾随边距为0(等于UIScrollView的边距)。

3)最重要的部分是设置宽度和高度,其中高度约束的优先级应该低。

private func setupConstraints() {

    // Constraints for scrollView
    scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

    // Constraints for containerView
    containerView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
    containerView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
    containerView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
    containerView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
    containerView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true

    let heightConstraint = containerView.heightAnchor.constraint(equalTo: scrollView.heightAnchor)
    heightConstraint.priority = UILayoutPriority(rawValue: 250)
    heightConstraint.isActive = true
}

我得到了同样的错误。我已经做了以下工作

视图(父视图) 滚动视图0,0600600 ScrollView中的UIView: 0,0,600,600 UIView包含图像视图,标签

现在为scrollView(2)和UIView(3)添加开头/结尾/顶部/底部。

选择视图(1)和视图(3)设置相同的高度和重量。它解决了我的问题。

我已经做了一个视频,这将会有所帮助:

https://www.youtube.com/watch?v=s-CPN3xZS1A

使用自动布局

在一个定义良好的视图中添加滚动视图,然后在滚动视图中添加堆栈视图

从滚动视图和堆栈视图中添加上、左、右、下、中心X和中心Y约束到相关的超级视图中

确保约束从堆栈视图链接到正确的父视图(scrollview),因为当前默认设置是添加Align Top约束,而不是Top Space约束。