UIScrollView可滚动内容大小模糊

Wir*_*ing 472 interface-builder uiscrollview ios autolayout swift

各位开发者,我在Interface Builder(Xcode 5/iOS 7)中遇到AutoLayout问题.这是非常基本和重要的,所以我想每个人都应该知道这是如何正常运作的.如果这是Xcode中的一个错误,那就是一个关键错误!

所以,每当我有一个像这样的视图层次结构时,我遇到了麻烦:

>UIViewController
>> UIView
>>>UIScrollView
>>>>UILabel (or any other comparable UIKit Element)
Run Code Online (Sandbox Code Playgroud)

UIScrollView具有可靠的约束,例如,每侧50 px(没问题).然后我向UILabel添加一个Top Space约束(没问题)(我甚至可以固定标签的高度/宽度,不做任何改变,但由于Label的内在大小,应该是不必要的)

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

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

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

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

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

我在一个新的项目中做了这个最小的例子,你可以下载并附上截图.如您所见,Interface Builder期望Label位于UIScrollView边界之外(橙色虚线矩形).使用Resolve Issues Tool更新Label的框架会将其移动到那里.

请注意:如果用UIView替换UIScrollView,行为就像预期的那样(Label的框架是正确的,并且根据约束条件).所以似乎UIScrollView存在问题,或者我错过了重要的事情.

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

帮助我Obi-Wan Kenobi!为什么模棱两可的布局?为什么错位的观点?

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

Interface Builder中的问题的插图

Mat*_*bbi 1026

注意:在iOS> 10.0上,尚未经过测试; 因此,在某些情况下解决方案可能不完整.

所以我只是这样整理出来:

  1. 在里面UIScrollView 添加一个UIView(我们可以称之为contentView);

  2. 在此contentView,将顶部,底部,左侧和右侧边距设置为0(当然是从scrollView哪个边缘开始superView); 设置水平和垂直对齐中心 ;

完了.

现在,您可以添加在您的所有意见contentView,并contentSizescrollView将与根据自动调整大小contentView.

更新:

一些特殊情况由本公约所涵盖的视频被贴@Sergio在下面的意见.

  • 这太棒了!中心X和Y是关键部分! (122认同)
  • 对于任何面临ScrollView不可滚动问题的人来说,设置contentView的底部和对齐中心垂直约束的优先级低,对我来说是个窍门! (41认同)
  • 这不会让它滚动. (39认同)
  • 几乎完美,除了scrollview无法再猜测内容的长度并相应调整大小以适应内部对象的contentSize.我在contentView里面有一个tableview,它的高度发生了变化(通过约束),而scrollview不允许我滚动. (31认同)
  • 也许这[视频](https://www.youtube.com/watch?v=UnQsFlMGDsI)可以帮助克服所有剩余的问题. (27认同)
  • 5年后,花了3个小时试图理解为什么我的imageView没有显示在scrollView上,我在这里记住了我自己的答案并解决了问题 - 这意味着即使在iOS12上工作,这个答案仍然有效。关键部分仍然是使视图居中。 (11认同)
  • 谢谢!有人可以解释这是如何工作的吗? (2认同)
  • @MatteoGobbi就是这样!它成功了!正在努力解决scrollView autoLayout疯狂这类问题2天....谢谢你老兄! (2认同)
  • 不行.视图不会滚动,因此不会自动调整contentSize的大小.为什么这么多的投票给一个小费,这基本上只是删除了IB中的错误,但是阻止了滚动?或者我错过了什么,这是不是说? (2认同)
  • 这个答案是错误的。请参阅答案中的视频链接 (2认同)
  • @Sergio,为什么需要`'Content View'.height == View.height`?它的高度不应该等于它的子视图高度吗? (2认同)
  • 只是想说我仍然遇到麻烦,直到我使用 Relation =“大于或等于”将内容视图的最底部元素(在我的例子中是 UILabel)固定到内容视图的底部。此后滚动就起作用了。 (2认同)
  • 请注意,我的回答已有 4.5 年的历史,几年前,Apple 解决了这个问题,在他们的 sdk 中实施了类似的解决方案。您今天找到的任何解决方案都不是我们拥有 iOS < 10 时所需的解决方案。 (2认同)
  • 这个答案对我不起作用,几乎......我必须在检查器中取消选择“内容布局指南”才能使其工作。 (2认同)

sel*_*ame 94

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

  • 谢谢您的回答!如果我理解正确,您可以通过将ScrollView中的每个子视图固定到顶部和底部来消除错误.但是,这不是必需的.您只需要确保有一种方法可以从滚动视图的顶部到底部形成连续的约束线.[-XXX]我希望这是可以理解的;> (30认同)
  • 是什么帮助我确保滚动视图固定到superview而不是顶部或底部布局指南.我删除了底部布局指南的约束,并通过菜单而不是界面构建器.编辑 - > Pin - >底层空间到Superview. (3认同)
  • 如果视图具有可变高度,如何解决问题?那么如何设置约束以便滚动视图可以计算大小? (2认同)
  • '你只需要确保有一种方法可以从滚动视图的顶部到底部形成连续的约束线'< - 感谢这句话 (2认同)
  • 如果您希望scrollview的宽度遵循手机屏幕的宽度或UI中的任何其他元素(如包含UIView),则需要使用滚动视图之外的另一个元素来设置"等宽". (2认同)

sky*_*der 62

这是我自己回答的问题的答案UIScrollView +中心视图+ Ambigous Scrollable内容大小+许多iPhone大小.

但它也完全覆盖了你的情况!

所以,这是最简单案例的初始状态:

  1. scrollView对所有边都有0个约束
  2. 按钮居中水平和垂直,具有固定的宽度和高度约束
  3. 而且,当然 - 恼人的警告 Has ambiguous scrollable content widthHas ambiguous scrollable content height.

1

所有,我们要做的是:

  • 添加2个附加约束,例如"0" 表示我们视图的尾部和/或底部空间(请参阅下面屏幕截图中的示例).

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

2

您可以在我的示例项目中查看它,演示如何解决此问题.

PS

根据逻辑 - 这个动作应该导致"冲突的约束".但不是!

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


小智 48

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

  • UIViewController
  • UIView '主视图'
    • UIScrollView
      • UIView '容器视图'
        • [您的内容]

第二步是制定UIScrollView约束.我使用topView的top,bottom,leading和trailing约束来做到这一点.

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

"具有模糊的可滚动内容宽度"和"具有模糊的可滚动内容高度"

与上述相同的约束继续,只是添加的约束Equal HeightEqual Width你的容器视图相对于主视图,并没有UIScrollView.换句话说,容器视图的约束与UIScrollView超级视图相关联.

之后,您的故事板中不会出现警告,您可以继续为子视图添加约束.

  • 同意 - 我认为添加容器视图是最好,最易维护的解决方案. (2认同)

Yod*_*ama 44

我遇到过同样的问题。取消选中此复选框。由于您是在代码中设置内容大小。 在此处输入图片说明


Đor*_*vić 43

iOS 12,Swift 4

最简单的方法autolayout:

  1. 添加UIScrollView并固定0,0,0,0到superview(或您想要的大小)
  2. 添加UIView滚动型,将其固定0,0,0,0到所有4个方面,并居中horizontallyvertically.
  3. 在尺寸检查器中,更改bottomalign center Y优先级为250.(对于水平滚动更改trailingalign center X)
  4. 将所需的所有视图添加到此视图中.不要忘记在最低视图上设置底部约束.

  • 要点4-第二句话很重要。 (3认同)
  • 我来自 Android 背景,所以我能说的是苹果正在与开发人员一起做些什么 (3认同)
  • 提示:对我来说,它只工作,如果我水平和垂直移除中心并用相等的宽度替换它(scrollView + view inside scrollView)并根据内容添加高度,这意味着视图的最后一个元素需要底部约束。在这里查看更多信息:/sf/answers/3820409491/ (2认同)

Wil*_* T. 24

我终于弄明白了,我希望这更容易理解.

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

在此输入图像描述

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

  • 您可以设置从内容视图到滚动视图的相等宽度和高度约束,而不是常量值.这将适用于所有决议. (8认同)

Wan*_*now 24

Xcode 11+, Swift 5

If you are wondering why all of the answers does not work anymore, make sure that you have pinned the content view (the one you've put inside the scroll view) to Content Layout Guide of the scroll view and NOT to Frame Layout Guide.

Content view edges (leading, trailing, top, bottom) should not be pinned like leading on the image - to Frame Layout Guide

不是这样

but like this - to Content Layout Guide.

从下拉列表中选择内容布局指南

在此处输入图片说明

And then the most of the answers will work for you.

The most simple approach now is going like this:

  1. Put scroll view in the root view
  2. Pin all the sides of scroll view to the superview
  3. Take another UIView (will call it content view) and put it inside the scroll view
  4. Pin all the sides of the content view to scroll view's Content Layout Guide
  5. Pin the content view's width to be equal to scroll view's Frame Layout Guide
  6. 以所需的任何方式修复内容视图的高度(在下面的示例中,我仅使用了恒定的高度约束)

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

在此处输入图片说明

  • 这个答案应该高于 (4认同)

Bor*_*rzh 16

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

对于内容视图,您需要将前导/尾随/顶部/底部空间的约束设置为scrollview,这不会更改内容视图框架,如下所示:在此输入图像描述

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

希望这可以帮助.


Gen*_*ent 7

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
}
Run Code Online (Sandbox Code Playgroud)


Mik*_*imz 6

看看这个非常快速和关于如何使滚动视图工作和使用自动布局完全滚动的点教程.现在,唯一让我感到困惑的是为什么滚动视图的内容大小总是比必要的大..

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


Nic*_*atz 5

对我来说,添加a contentView并没有真正按照建议的方式工作。此外,由于添加了视图,因此会产生开销(尽管我认为这不是一个大问题)。对我来说最有效的方法就是关闭的歧义检查scrollView。一切都布置得很好,所以我认为在像我这样的简单情况下还可以。但是请记住,如果您遇到其他限制scrollView,Interface-Builder不会警告您。

在此处输入图片说明

  • 这只会删除警告,并且无法解决问题。 (4认同)

归档时间:

查看次数:

246918 次

最近记录:

5 年,9 月 前