UIScrollView可滚动内容大小歧义

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

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

的UIViewController

的UIView

UIScrollView中

UILabel(或任何其他可比的UIKit元素)

UIScrollView有严格的约束条件,例如,从每边50像素(没问题)。 然后,我添加顶部空间约束UILabel(没问题)(我甚至可以钉高度/宽度的标签,什么都不改变,但由于标签的固有尺寸,应该是不必要的)

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

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

现在发生了两个警告 – 我不明白为什么:

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

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

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

请注意:如果用UIViewreplaceUIScrollView,则行为与预期的一样(标签的框架是正确的,并且是根据约束)。 所以似乎或者是UIScrollView的问题,或者我错过了一些重要的东西。

当我运行应用程序而没有更新IBbuild议的标签框架时,它的位置就好,它应该在哪里,UIScrollView是可以滚动的。 如果我更新框架的标签不见了,UIScrollView不滚动。

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

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

界面生成器中的问题的插图

所以我就这样整理:

  1. UIScrollView 添加一个UIView (我们可以调用contentView );

  2. 在这个contentView将顶部,底部,左侧和右侧边距设置为0 (当然是从scrollViewsuperView ); 设置也alignment中心水平和垂直 ;

完成

现在,您可以在contentView添加所有视图, scrollViewcontentSize将根据contentView自动resize。

更新:

@Sergio在下面的评论中发布的video介绍了一些特殊情况。

这个错误花了我一段时间来追查,最初我试图固定ScrollView的大小,但错误消息清楚地说“内容大小”。 我确定从ScrollView顶部固定的所有东西都固定在底部。 这样ScrollView就可以通过查找所有对象和约束的高度来计算它的内容高度。 这解决了含糊不清的内容高度,宽度是非常相似的…最初,我有大多数的东西在ScrollView居中,但我也必须将对象固定在ScrollView的一侧。 我不喜欢这个,因为iPhone6可能有一个更宽的屏幕,但它会消除“模棱两可的内容宽度”的错误。

这是我自己回答的问题的答案UIScrollView +集中查看+ Ambigous滚动内容大小+许多iPhone的大小 。

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

所以,这里是最简单情况的初始状态:

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

1

所有,我们要做的是:

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

重要:您必须添加尾部和/或底部约束。 不是“领先和顶尖” – 这是行不通的!

2

你可以在我的示例项目中查看它,演示如何解决这个问题。

PS

根据逻辑 – 这一行动应该导致“冲突约束”。 但不是!

我不知道它为什么会起作用,Xcode如何检测哪个约束更优先(因为我没有为这些约束设置优先级)。 我会很感激,如果有人解释,为什么它在下面的意见。

我有同样的问题,并通过文件search后,找不到一个可以接受的解决scheme。 您需要创build一个UIView作为UIScrollView的子视图,如下所述:

  • 的UIViewController
  • UIView的“主视图”
    • UIScrollView中
      • UIView“容器视图”
        • [您的内容]

第二步是制作UIScrollView约束。 我用超级视图的顶部,底部,前后约束做了这个。

接下来,我添加了UIScrollView的容器约束,这里是问题的开始。 当您放置相同的约束(顶部,底部,前后)时,故事板会显示一条警告消息:

“模糊的可滚动内容宽度”和“模糊的可滚动内容高度”

继续使用上面的相同约束,只需将约束“ Equal Height ”和“ Equal Width ”添加到Container视图中,而不是与您的UIScrollView相关。 换句话说,容器视图的约束与UIScrollView的超视图相关联。

之后,在Storyboard中不会有警告,您可以继续为子视图添加约束。

我希望这可以帮助别人。

我终于明白了这一点,我希望这更容易理解。

你肯定需要添加一个基本的UIView作为一个“内容视图”的滚动视图,他们提到,并使其大小相同的滚动视图,并在这个内容视图,设置这6个参数。

在这里输入图像描述

正如你所看到的,你需要6个参数! 其中..在正常情况下,你重复2个约束,但这是避免这个故事板错误的方法。

我知道我可能会迟到,但下一个解决scheme解决了这种问题,无需额外的代码 ,只是使用故事板:

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

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

希望这可以帮助。

看看这真的很快,并点教程如何让滚动视图工作,并与自动布局完全滚动。 现在,唯一让我感到困惑的是为什么滚动视图的内容大小总是比较大,因此是必要的。

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

请参阅下面的内容:scrollview中的内容视图纵向和横向集中。 你有歧义错误,总是要确保两个从你的内容视图添加到滚动视图是1)。button空间容器.2)拖尾空间约束,在屏幕截图突出显示,

这些约束意味着滚动是多less你可以滚动后,你的内容视图的高度或宽度。

在这里输入图像描述

它可能会帮助你。

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

对于我来说,添加一个contentView并没有真正的build议。 而且,由于增加了视图,所以会产生开销(尽pipe我不认为这是一个大问题)。 什么对我最有效的只是closures模糊检查我的scrollView 。 一切都很好,所以我觉得在我这样简单的情况下是可以的。 但请记住,如果您的scrollView其他约束中断,Interface-Builder将不会再提醒您。

在这里输入图像描述

在UIScrollView中使用contentView(UView)作为容器,粘贴到superview(UIScrollView)的边缘(顶部,底部,尾部,顶部),contentView应该和superview具有相同的宽度和高度。 那些是限制。 和方法的调用:

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

解决了我的问题。

与uiscrollview挣扎的人不滚动只是设置你的内容视图的底部约束与你最后一个视图的底部布局(这是在你的内容视图内)。 不要忘记删除中心的Y约束。

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

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

我所做的是创build一个单独的内容视图,如下所示。

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

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

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

带有ContentView的UIScrollView通过Interface Builder

我得到了同样的错误..我已经做了以下

  1. 查看(上海华)
  2. ScrollView 0,0,600,600
  3. ScrollView中的UIView:0,0,600,600
  4. UIView包含图像视图,标签

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

select视图(1)和视图(3)设置同样的高度和重量..它解决了我的问题。

我已经做了video,将有助于:

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

[在XCode 7.2和iOS 9.2中testing]

什么抑制了故事板错误和警告我设置滚动视图和内容视图的内在大小 (在我的情况下,一个stackview) 占位符 。 此设置位于情节提要中的“尺寸”检查器中。 它说 – 设置一个devise时间固有的内容大小只影响一个视图,而在Interface Builder中编辑。 视图在运行时不会有这种内在的内容大小。

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

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

故事板上的警告让我很生气,我不想把事情水平或垂直居中,只是为了压制警告。

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

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

这是来自Apple的文档 。 例如,如果您不小心将顶部的Label / Button / Img / View固定在滚动区域之外的视图(也许是一个标题或scrollView上面的某个东西?)而不是contentView,则会冻结整个contentView。

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

自定义视图是图像中标记的ContentView

将所有的子视图添加到内容视图。 在某些情况下,您将看到滚动内容视图的内容大小不明确,您应该select内容视图,然后单击“解决自动布局问题”button(在IB布局的右下angular),然后select“添加缺less约束“选项。

在这里输入图像描述

从现在起当你运行项目时,滚动视图会自动更新它的内容大小,不需要额外的代码。

你只需要确保有一种方法可以从scrollview的顶部到底部形成一个连续的约束。 [-XXX]

在我的情况下 – 一个水平滚动的滚动视图 – 我还需要为滚动视图的每个孩子添加宽度和高度的限制,虽然苹果的技术说明并没有告诉你这一点。

在Interface Builder的大小检查器中将ViewController的大小(保持UIScrollView的大小)设置为Freeform,并且全部都可以工作。

包含UIViewcontroller的界面生成器中的大小检查器中的自由forms设置

使用自动布局的最简单的方法是:

  1. 添加UIScrollView并将其钉在0,0,0,0超级查看(或您所需的大小)
  2. 在ScrollView中添加UIView,把它固定到所有的4边,并且水平和垂直居中。
  3. 在尺寸检查员中,将“底部”和“alignment中心Y”优先级改为250。
  4. 将所需的所有视图添加到此视图中。 不要忘记在最低视图上设置底部约束。

我在youTube上做了一个video
在Xcode中只使用Storyboard滚动StackViews

我认为2种情况可以出现在这里。

scrollView里面的视图 –

  1. 没有任何内在的内容大小(例如UIView
  2. 确实有它自己的内容大小(例如UIStackView

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

  1. 从顶部,左侧,底部和右侧4个约束。

  2. 等于滚动视图的宽度(停止水平滚动)

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

在这里输入图像描述

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

在这里输入图像描述

在scrollview中的所有子视图都必须有触及scroll view的所有边界的约束,正如文档中所解释的那样,滚动视图的高度和宽度是由子视图中的度量自动计算的,这意味着您需要宽度的尾随和主要约束以及高度的顶部和底部约束。

我认为从现在开始是一个十秒钟的工作。 我在XCode 7.3中观察它,并制作了一个video。 在这里检查:

https://www.youtube.com/watch?v=yETZKqdaPiI

所有你需要做的,添加一个子视图到相同的宽度和高度的UIScrollView 。 然后selectViewController并按Reset to suggested constraint 。 请检查video清楚的理解。

谢谢