ChatGPT解决这个技术问题 Extra ChatGPT

UIScrollView 可滚动内容大小歧义

开发人员,我在 Interface Builder (Xcode 5 / iOS 7) 中遇到自动布局问题。这是非常基本和重要的,所以我认为每个人都应该知道它是如何正常工作的。如果这是 Xcode 中的一个错误,那就是一个严重的错误!

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

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

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

当我向 UILabel 添加尾随约束时,麻烦就开始了:

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

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

A) Scrollable Content Size Ambiguity (Scroll View has ambiguous scrollable content height/width)

B) 错位的视图(标签预期:x= -67 实际:x= 207

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

请注意:如果您将 UIScrollView 替换为 UIView,则行为符合预期(Label 的框架是正确的并且符合约束)。所以似乎 UIScrollView 有问题,或者我错过了一些重要的事情。

当我运行应用程序而不按照 IB 的建议更新标签的框架时,它的位置很好,正是它应该在的位置,并且 UIScrollView 是可滚动的。如果我确实更新了框架,则标签不在视线范围内,并且 UIScrollView 不会滚动。

帮助我欧比旺克诺比!为什么是模棱两可的布局?为什么会有错位的看法?

您可以在此处下载示例项目并尝试了解发生了什么:https://github.com/Wirsing84/AutoLayoutProblem

https://i.stack.imgur.com/eqoUh.png

尝试将 UILabel 放在内容视图中,然后将标签的后沿设置为内容视图(常规 UIView)。该视频可能对您有很大帮助:youtube.com/watch?v=PgeNPRBrB18&feature=youtu.be
很棒的视频,但它没有为我解决警告。 :(
非常感谢您的视频 - 我从中学到了很多(相当令人惊讶)!但是,当我将视频知识与 stackoverflow.com/questions/18953617/… 结合起来时,我可以修复警告。剩下的问题是:如何使 scrollView 的 contentView 大小只有必要的大?
观看 this 视频。它展示了如何在 XCode 5 / iOS 7 中使用 UIScrollLayout 和自动布局。
我的建议是不要直接使用 UIScrollView。而是尽可能地使用 UICollectionViewUITableView,大多数情况下这些元素都可以实现,并且它还提供了简单性、可读性和可重用性!!!

M
Matteo Gobbi

更新

如今,Apple 意识到了我们多年前解决的问题 (lol_face),并提供了 Content Layout GuideFrame Layout Guide 作为 UIScrollView 的一部分。因此,您需要执行以下步骤:

同上;对于这个contentView,设置top、bottom、left、right margins为0,将它们固定到滚动视图的Content Layout Guide;现在将 contentView 的高度设置为 Frame Layout Guide 的高度。对宽度做同样的事情;最后,将等高约束的优先级设置为 250(如果需要视图垂直滚动,则宽度水平滚动)。

完成的。

现在您可以在该 contentView 中添加所有视图,scrollViewcontentSize 将根据 contentView 自动调整大小。

不要忘记从 contentView 中最后一个对象的底部到 contentView 的边距设置约束。

原创 [已弃用]

在 UIScrollView 里面添加一个 UIView(我们可以称之为 contentView);在这个contentView中,设置top、bottom、left、right margins为0(当然是从scrollView也就是superView);还设置水平和垂直对齐中心;


几乎完美,除了滚动视图不能再猜测您的内容的长度并相应地调整它的 contentSize 以适应里面的对象。我在 contentView 中有一个 tableview,它的高度发生了变化(通过约束),并且滚动视图不允许我滚动。
也许这个 video 可以帮助克服所有剩余的问题。
这不会使它滚动。
对于任何面临 ScrollView 不可滚动问题的人,设置 contentView 的底部并以低优先级垂直对齐中心约束对我来说是诀窍!
5 年后,花了 3 个小时试图理解为什么我的 imageView 没有出现在 scrollView 上,我记得我自己的答案并解决了问题😂-这意味着即使在 iOS12 上工作,这个答案仍然有效。关键部分仍然使视图居中。
T
Top-Master

Xcode 11+

使用 autolayout 的最简单方法:

添加 UIScrollView 并将其 0,0,0,0 固定到超级视图(或您想要的大小) 在 ScrollView 中添加 UIView 类型的容器,将其 0,0,0,0 固定到所有 4 个边并水平和垂直居中。在容器的大小检查器中,将底部和对齐中心 Y 优先级更改为 250。(对于水平滚动更改尾随和对齐中心 X)将您需要的所有视图添加到所述容器(UIView)中。不要忘记在最低视图上设置底部约束。选择 UIScrollView,选择尺寸检查器并取消选择 Content Layout Guides。


我无法设置滚动视图的内容高度,但它可以工作。 :)
提示:只有当我水平和垂直移除中心并将其替换为等宽(scrollView + scrollView 内的视图)并根据内容添加高度时,它才有效,这意味着视图的最后一个元素需要底部约束。在这里查看更多信息:stackoverflow.com/a/54577278/5056173
肖恩,我每天都在使用这个,当涉及到垂直和水平滚动视图滚动时,我从来没有遇到过这种方法的问题。也许您忘记对最低/最后一个元素设置底部约束。没有它,这是行不通的。
第 4 点 - 第二句是重点。
我来自Android背景,所以我可以说的是苹果正在与开发人员一起做的WTF
W
WantToKnow

Xcode 11+,斯威夫特 5

如果您想知道为什么所有答案都不再起作用,请确保您已将内容视图(您放置在滚动视图中的那个)固定到滚动视图的内容布局指南而不是框架布局指南。

内容视图边缘(前导、尾随、顶部、底部)不应像图像上的前导一样固定 - 框架布局指南

https://i.stack.imgur.com/qZKwc.png

但像这样 - 内容布局指南。

https://i.stack.imgur.com/nlqlw.png

https://i.stack.imgur.com/R1072.png

然后大多数答案都会为您服务。

现在最简单的方法是这样的:

将滚动视图放在根视图中 将滚动视图的所有边固定到超级视图 取另一个 UIView(称为内容视图)并将其放在滚动视图中 将内容视图的所有边固定到滚动视图的内容布局指南 固定内容视图的宽度等于滚动视图的框架布局指南 以您想要的任何方式修复内容视图的高度(我在下面的示例中只使用了恒定高度约束)

总体而言,您在最简单实现中的结构将如下所示

https://i.stack.imgur.com/FgNUz.png


@WantToKnow 不需要限制高度,只需将其优先级更改为低(250)
Xcode 11+,Swift 5。根据@WantToKnow 的回答,我解决了我的问题,我准备了 [video][1] 和 [code][2] [1]: youtube.com/watch?v=qMrH5_Yj5hM [2]: github.com/AhmAbdallah/CustomCollectionView
仅当我将底部约束添加到内容视图的最后一个元素时,这才对我有用
有时我真的很讨厌苹果。他们可以向 Xcode 添加新功能,但这些功能不应该改变默认行为。
这个答案应该在上面
s
self.name

这个错误花了我一段时间才找到,最初我尝试固定 ScrollView 的大小,但错误消息清楚地显示“内容大小”。我确保从 ScrollView 顶部固定的所有内容也固定在底部。这样,ScrollView 可以通过查找所有对象和约束的高度来计算其内容高度。这解决了不明确的内容高度,宽度非常相似......最初我将大多数东西 X 放在 ScrollView 的中心,但我还必须将对象固定到 ScrollView 的一侧。我不喜欢这样,因为 iPhone6 可能有更宽的屏幕,但它会消除“模糊内容宽度”错误。


谢谢您的回答!如果我理解正确,您可以通过将 ScrollView 中的每个子视图固定到顶部和底部来消除错误。但是,这不是必需的。您只需要确保有一种方法可以从滚动视图的顶部到底部创建连续的约束线。 [-XXX] 我希望这是可以理解的;>
如果视图具有可变高度,如何解决问题?那么如何设置约束以便滚动视图可以计算大小?
'你只需要确保有一种方法可以从滚动视图的顶部到底部进行连续的约束'<-感谢那句话
帮助我的是确保滚动视图被固定到超级视图而不是顶部或底部布局指南。我删除了底部布局指南的约束并通过菜单而不是界面构建器。编辑器 -> 引脚 -> 底部空间到 Superview。
如果您希望滚动视图的宽度跟随手机屏幕或 UI 中任何其他元素的宽度(如包含 UIView),您需要使用滚动视图之外的另一个元素在其上设置“等宽”以进行测量。
C
Community

这是我的自我回答问题 UIScrollView + Centered View + Ambigous Scrollable Content Size + many iPhone sizes 的答案。

但它也完全涵盖了您的情况!

因此,这是最简单情况的初始状态:

scrollView 对所有边缘的约束为 0 按钮居中水平和垂直,具有固定的宽度和高度约束,当然 - 烦人的警告 具有不明确的可滚动内容宽度和不明确的可滚动内容高度。

https://i.imgur.com/d5Fgmzg.png

我们要做的就是:

添加 2 个额外的约束,例如“0”表示我们视图的尾随和/或底部空间(请看下面的屏幕截图示例)。

重要提示:您必须添加尾随和/或底部约束。不是“领先和顶级” - 它不起作用!

https://i.imgur.com/7yEMQ7J.png

您可以在我的 example project 中查看它,它演示了如何解决此问题。

附言

根据逻辑 - 此操作应导致“冲突约束”。但不是!

我不知道它为什么起作用以及 Xcode 如何检测哪个约束的优先级更高(因为我没有明确为这些约束设置优先级)。如果有人在下面的评论中解释为什么它有效,我将不胜感激。


很棒的提示!我最终只是为底部边缘创建了一个约束并将优先级设置为中或低
哇!这严重没有任何意义,但有效!谢谢!在我看来,最后一项我将底部约束设置为 0 和 BANG。终于奏效了。
D
Dale K

您需要创建一个 UIView 作为 UIScrollView 的子视图,如下所述:

UIViewController

UIView '主视图' UIScrollView UIView '容器视图' [你的内容]

UIScrollView UIView 'Container View' [你的内容]

UIView 'Container View' [你的内容]

[您的内容]

第二步是制作 UIScrollView 约束。我使用其 superView 的顶部、底部、前导和尾随约束来完成此操作。

接下来,我为 UIScrollView 的容器添加了约束,这就是问题的开始。当您放置相同的约束(顶部、底部、前导和尾随)时,情节提要会发出警告消息:

“具有不明确的可滚动内容宽度”和“具有不明确的可滚动内容高度”

继续使用上述相同的约束,只需将约束 Equal HeightEqual Width 添加到与 相关的 Container View >主视图您的UIScrollView。换句话说,容器视图的约束与 UIScrollView 的超级视图相关联。

之后,您的 Storyboard 中将不会出现警告,您可以继续为子视图添加约束。


同意 - 我认为添加容器视图是最好的、最可维护的解决方案。
当您没有要管理的导航栏时,此解决方案将起作用。
Y
Yodagama

https://i.stack.imgur.com/GfdTt.png


W
William T.

我终于想通了,我希望这更容易理解。

您通常可以通过将基本 UIView 作为“内容视图”添加到滚动视图来绕过该警告,正如他们所提到的,并使其与滚动视图的大小相同,并在此内容视图上设置这 6 个参数。

https://i.stack.imgur.com/G0Tgt.png

如您所见,您总共需要 6 个参数!哪个..在正常情况下,您要复制 2 个约束,但这是避免此情节提要错误的方法。


以上几乎对我有用,因为我担心 3 种不同的屏幕宽度(4/5、6、6+)我将内容视图和滚动视图设置为具有相等的宽度。你是对的,它是重复的,因为我已经告诉内容视图有 0 个前导和结束空间。
您可以设置从内容视图到滚动视图的相等宽度和高度约束,而不是恒定值。这适用于所有分辨率。
我必须实现相同的,所以你能帮我为内容视图和滚动视图设置相同的高度和宽度吗?
可能值得检查一下你是否仍然需要这样做。我最近在滚动视图中设置了一个 imageView 并且能够逃脱只设置顶部显示的 4 个约束以使错误在 Xcode 8.3 中消失
@Honey 这是 3 年前发布的。从那时起,他们肯定改进了故事板。我也注意到你现在可以在没有内容视图的情况下逃脱。我会调整我的答案。
B
Borzh

我知道我可能会迟到,但下一个解决方案无需额外代码即可解决此类问题,只需使用情节提要:

https://i.stack.imgur.com/CMG4w.png

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

希望这可以帮助。


N
Nick Podratz

对我来说,添加 contentView 并没有真正按照建议工作。此外,由于添加了视图,它会产生开销(尽管我不认为这是一个大问题)。对我来说最有效的方法就是关闭我的 scrollView 的歧义检查。一切都很好,所以我认为在像我这样的简单情况下没关系。但请记住,如果您的 scrollView 的其他约束中断,Interface-Builder 将不会向您发出更多警告。

https://i.stack.imgur.com/F5Muh.jpg


这只会删除警告,而不会解决问题。
你。是。我的。英雄。没有意识到这存在并且很高兴找到它!我尝试了您期望的“仅验证位置”,我不知道,仅验证位置,但不,它也允许这个错误的“内容大小”问题。必须选择“从不验证”。谢谢!
如果您以编程方式创建子视图,我认为这是正确的答案。谢谢!
M
Mike Simz

查看这个非常快速且重点明确的教程,了解如何使用自动布局使滚动视图正常工作并完全可滚动。现在,唯一仍然让我感到困惑的是为什么滚动视图内容的大小总是比必要的大..

http://samwize.com/2014/03/14/how-to-use-uiscrollview-with-autolayout/


G
Gent

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
}

R
Ravi Kumar

见下文:scrollview 中的内容视图垂直和水平集中。您遇到歧义错误,请始终确保从内容视图添加到滚动视图中的两个是 1).button 空间到 container.2)尾随空间到在屏幕截图中突出显示的约束,

滚动中的这些约束意味着您可以在内容视图高度或宽度之后滚动多少。

https://i.stack.imgur.com/mKvvT.png

它可能会帮助你。


L
Linh Dao

https://i.stack.imgur.com/OWk8C.png

以下两个约束解决了我的问题:

trailing = Stack View.trailing - 10
bottom = Stack View.bottom + 76

其中: trailing,bottom 是 UIScrollView 的尾随、底部


通过添加“到底部”约束,这对我有用。现在我想起来,这完全有道理。
R
Rishil Patel

使用 contentView (UView) 作为 UIScrollView 内的容器,坚持超级视图 (UIScrollView) 的边缘 (top, bottom, trailing, leading) 和 contentView 应该有 equalwidth equalheight 进行监督。这些都是约束。并调用方法:

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

为我解决了问题。


D
Daljeet Seera

在我的情况下,我收到了 iPad 中不正确的内容大小和内容大小歧义的问题,但在 iPhone 的情况下工作。我在情节提要中进行了以下更改以解决该问题。

在 UIView 中添加滚动视图,并将前导、顶部、尾随和底部约束添加到 0,0,0,0。根据例如要求设置滚动视图的高度。 100. 将 UIView 添加到滚动视图,并将前导、顶部、尾随和底部约束添加到 0,0,0,0 并对齐 center(X) 和 center(Y) 约束。在滚动视图的大小检查器中取消选择“内容布局指南”。


y
ygweric

@Matteo Gobbi 的回答很完美,但在我的情况下,滚动视图无法滚动,我删除“对齐中心 Y”并添加“高度 >=1”,滚动视图将变为可滚动


S
Siddhesh Mahadeshwar

与 uiscrollview 不滚动作斗争的人只需使用最后一个视图的底部布局(位于内容视图内部)设置内容视图的底部约束。不要忘记删除中心 Y 约束。

其余所有约束与上面定义的相同。 Scrollview 只关心从它的内容视图中获取最大高度,我们将它设置为最后一个视图的底部约束,这意味着滚动视图会自动改变它的内容偏移量。

在我的情况下,最后一个视图是 UILable,没有行属性 = 0(根据其内容自动调整其高度),因此它动态增加 uilable 的高度,最终我们的可滚动区域增加,因为 uilable 的底部布局与我们的内容视图的底部对齐,这迫使滚动视图增加它的内容偏移量。


W
Warif Akhand Rishi

我在 YouTube 上制作了一个视频
Scroll StackViews using only Storyboard in Xcode

我认为这里会出现两种情况。

scrollView 内的视图 -

没有任何内在内容大小(例如 UIView) 确实有自己的内在内容大小(例如 UIStackView)

对于这两种情况下的垂直可滚动视图,您需要添加以下约束:

来自顶部、左侧、底部和右侧的 4 个约束。与滚动视图等宽(停止水平滚动)

对于具有自己的内在内容高度的视图,您不需要任何其他约束。

https://i.stack.imgur.com/z7avH.png

对于没有任何内在内容高度的视图,您需要添加高度约束。仅当高度约束大于 scrollView 的高度时,视图才会滚动。

https://i.stack.imgur.com/eyiLH.png


V
Victor Doshenko

如果 UIScrollView 仍有问题,只需关闭 Content Layout Guides(在 xcode Interface Builder 中选择您的 ScrollView -> 在右侧面板中选择 Size 检查器 -> 取消选择“Content Layout Guides”)或尝试这些步骤: xcode 11 scroll view layouts - 它对于新的布局样式很有用。适用于 macOS 10.15.2、Xcode 11.3.1,适用于 05.02.2020

see screenshot


谢谢 !!救救我
m
mfaani
import UIKit

class ViewController: UIViewController {

    //
    let scrollView: UIScrollView = {
        
        let sv = UIScrollView()
        sv.translatesAutoresizingMaskIntoConstraints = false
        return sv
    }()
    
    let lipsumLbl: UILabel = { // you can use here any of your subview
        
        let lbl = UILabel()
        lbl.translatesAutoresizingMaskIntoConstraints = false
        lbl.text = """
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce eleifend nisi sit amet mi aliquet, ut efficitur risus pellentesque. Phasellus nulla justo, scelerisque ut libero id, aliquet ullamcorper lectus. Integer id iaculis nibh. Duis feugiat mi vitae magna tincidunt, vitae consequat dui tempor. Donec blandit urna nec urna volutpat, sit amet sagittis massa fringilla. Pellentesque luctus erat nec dui luctus, sed maximus urna fermentum. Nullam purus nibh, cursus vel ex nec, pulvinar lobortis leo. Proin ac libero rhoncus, bibendum lorem sed, congue sapien. Donec commodo, est non mollis malesuada, nisi massa tempus ipsum, a varius quam lorem vitae nunc.
        
        Cras scelerisque nisi dolor, in gravida ex ornare a. Interdum et malesuada fames ac ante ipsum primis in faucibus. Maecenas vitae nisl id erat sollicitudin accumsan sit amet viverra sapien. Etiam scelerisque vulputate ante. Donec magna nibh, pharetra sed pretium ac, feugiat sit amet mi. Vestibulum in ipsum vitae dui vehicula pulvinar eget ut lectus. Fusce sagittis a elit ac elementum. Fusce iaculis nunc odio, at fermentum dolor varius et. Suspendisse consectetur congue massa non gravida. Sed id elit vitae nulla aliquam euismod. Pellentesque accumsan risus dolor, eu cursus nibh semper id.
        
        Vestibulum vel tortor tellus. Suspendisse potenti. Pellentesque id sapien eu augue placerat dictum. Fusce tempus ligula at diam lacinia congue in ut metus. Maecenas volutpat tellus in tellus maximus imperdiet. Integer dignissim condimentum lorem, id luctus nisi maximus at. Nulla pretium, est sit amet mollis eleifend, tellus nulla viverra dolor, ac feugiat massa risus a lectus. Pellentesque ut pulvinar urna, blandit gravida ipsum. Nullam volutpat arcu nec fringilla auctor. Integer egestas enim commodo, faucibus neque ac, rutrum magna. Vivamus tincidunt rutrum auctor. Cras at rutrum felis. Fusce elementum lorem ut pharetra venenatis.
        """
        lbl.textColor = .darkGray
        lbl.font = UIFont.systemFont(ofSize: 16)
        lbl.numberOfLines = 0
        return lbl
    }()
    
    //======================================================================//
    //
    // MARK:- viewDidLoad
    //
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupViews()
        setupAutoLayout()
    }
    
    func setupViews() {
        
        title = "ScrollView Demo"
        view.backgroundColor = .white
        view.addSubview(scrollView)
        scrollView.addSubview(lipsumLbl)
    }
    
    func setupAutoLayout() {
        
        scrollView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        scrollView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        
        lipsumLbl.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
        lipsumLbl.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        lipsumLbl.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        lipsumLbl.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
    }
}

输出:

https://i.stack.imgur.com/MCMgz.gif


当您已经拥有 leftAnchor 时,为什么还需要leadingAnchor ?
leftAnchor 不能用于此目的,因此我们必须使用leadingAnchor 来实现相同的目的..
你在你的例子中都使用了。
@ShadeToD 让我检查一下
D
Dave G

如果有人发现您注意到右侧的滚动条滚动但内容没有移动,那么这个事实可能值得考虑:

您还可以在滚动视图的内容和滚动视图之外的对象之间使用约束来为滚动视图的内容提供固定位置,使该内容看起来漂浮在滚动视图上。

这来自 Apple 的 documentation。例如,如果您不小心将顶部的 Label/Button/Img/View 固定到滚动区域之外的视图(可能是标题或滚动视图上方的其他内容?)而不是 contentView,您将冻结整个 contentView。


B
Bitcon

垂直滚动

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


m
mfaani

对于任何视图,框架及其内容的大小都是相同的,即如果您有一些大小为 200 * 800 的内容(例如图像),那么它的框架也是 200 * 800。

这不适用于滚动视图的内容。内容通常大于滚动视图的框架大小。如果内容的宽度相同,那么您只能垂直滚动。如果它的高度相同,那么您只能水平滚动。因此,它是唯一需要 6 个约束而不是 4 个的视图。对于任何其他具有超过 4 个必需约束的视图,都会导致冲突。

要设置你的滚动视图,它的内容和滚动位置,你基本上需要回答三个问题:

我的框架有多大?即在任何给定时刻滚动视图应该有多大?例如,我只想使用屏幕高度的一半,所以

scrollview.frame = (x: 0, y:0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height / 2)

我需要多少滚动空间?即内容有多大?例如,框架可以只有 500 点的宽度,但是您可以设置具有 7000 点的图像,这需要相当长的时间来水平滚动。或者让它正好是 500 点的宽度,这意味着不会发生水平滚动。你现在滚动了多少?假设您的内容(或图像)宽度为 7000,帧大小仅为 500。要到达图像的末尾,您需要向右滚动 6500 点。第三部分确实不影响约束。你现在可以忽略它。理解它只会有助于滚动视图的工作方式。

解决方案

基本上,如果您遗漏了 2 个额外的约束(关于内容大小),那么布局引擎会因为歧义而抱怨。它不会知道内容的哪些区域被隐藏(在 scrollView 中不可见)以及内容的哪些区域不隐藏(在 scrollView 中可见)。

因此,请确保您也为内容添加了大小限制。有关详细信息,请参阅 this answer

但有时我不会在我的视图中添加大小限制,它就可以工作。这是为什么?

如果您添加到滚动视图中的所有内容都被限制在滚动视图的边缘,那么随着内容的增长,滚动视图将添加空间来容纳。只是您可能正在使用 intrinsicContentSize0UIView,因此 scrollView 仍会抱怨其 内容 的歧义。但是,如果您使用了 UILabel 并且它有一个非空文本,那么它的 intrinsicContentSize 会被设置(基于字体大小和文本长度以及换行符等),因此 scrollView 不会抱怨它的歧义.


V
Vlad

我所做的是创建一个单独的内容视图,如此处所示。

内容视图是自由形式的,可以将所有子视图添加到其中,并具有与 contentView 相关的约束。

UIScrollView 被添加到主视图控制器。

以编程方式,我将通过 IBOutlet 链接的 contentView 添加到类并设置 UIScrollView 的 contentView。

https://i.stack.imgur.com/DneL7.png


V
Vinod Joshi

我遇到了同样的错误..我已经完成了以下操作

View(Superview) ScrollView 0,0,600,600 UIView inside ScrollView : 0,0,600,600 UIView 包含图像视图,标签

现在为 scrollView(2) 添加前导/尾随/顶部/底部,然后是 UIView(3)。

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

我已经完成了有帮助的视频:

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


g
gtl_pm

[在 XCode 7.2 和 iOS 9.2 中测试]

对我来说,抑制 Storyboard 错误和警告的原因是将滚动视图和内容视图(在我的情况下是堆栈视图)的固有大小设置为占位符。此设置可在 Storyboard 的大小检查器中找到。它说 - 设置设计时内在内容大小只会影响在 Interface Builder 中编辑时的视图。视图在运行时不会有这个内在的内容大小。

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

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

故事板警告让我发疯,我不想为了压制警告而将事物水平或垂直居中。


s
supergegs

正如前面的答案中提到的,您应该在滚动视图中添加一个自定义视图:

https://i.stack.imgur.com/Q18qS.png

将所有子视图添加到内容视图。在某些时候您会看到滚动内容视图具有不明确的内容大小警告,您应该选择内容视图并单击“解决自动布局问题”按钮(在 IB 布局的右下角),然后选择“添加缺失约束”选项。

https://i.stack.imgur.com/jQQT2.png

从现在开始,当您运行项目时,滚动视图将自动更新其内容大小,无需额外代码。


j
johnnyMac

您只需要确保有一种方法可以从滚动视图的顶部到底部创建连续的约束线。 [-XXX]

在我的例子中——一个水平滚动的滚动视图——我还需要为滚动视图的每个子视图添加宽度和高度约束,尽管 Apple's technical note 没有告诉你这一点。


n
nico

在 Interface Builder 的大小检查器中将 ViewController(持有 UIScrollView 的那个)大小设置为 Freeform,一切都应该工作。

Freeform setting in Size inspector in Interface Builder for the containing UIViewcontroller