4

我的故事板上有一个UIViewController横向并排的 2 个子视图。我添加了约束以将前缘和后缘固定为常数(20 分),并添加了另一个约束以保持宽度相等。如果我假设以下,应该可以计算出每个子视图的宽度需要:

  • 子视图不重叠
  • 没有其他视图存在(至少在水平方向上)
  • 屏幕的宽度(超级视图)是已知的

然而,XCode 给了我一个警告,我的观点在水平方向上是模棱两可的。我猜这意味着 XCode 没有做出这些假设之一,但它是哪一个?有没有办法让我指示 XCode 做出这个假设?

编辑:好的,玩了一下,警告消失了,但看起来它并没有做出第一个假设——它只是将每个子视图的宽度设置为superview.width - 40,并愉快地将一个视图埋在另一个视图下面。所以问题是如何阻止它们重叠?

编辑 2:好的,我的实际屏幕比我的简单示例复杂得多。这是我得到的:

在此处输入图像描述

所以在这个设置中,我有 4 个垂直和水平交错的视图。我希望蓝色、红色和紫色视图都相同subview.frame.size.width = superview.width - 60。蓝色和紫色排列在左列,红色单独在右列,所有间隙(两列之间以及每列与其最近的边缘之间)都保持不变(20 pts)。这 3 张桌子的高度可变,我将按照James 的回答here中所述以编程方式设置. 底部是一个粉红色视图,它延伸了屏幕的宽度(减去间隙),并且位于紫色或红色视图下方 20 点的恒定位置,以较低者为准(我试图通过给它一个每个视图的间距约束 >= 20,我希望它会为其中一个准确选择 20)。由于所有高度都是动态的,并且可能不一定同时适合屏幕,因此我将它们的 superview aUIScrollView而不是 normal UIView

当一切都说完了,我仍然收到一个警告,我的所有 4 个视图在水平方向上都是模棱两可的,而粉色条在垂直方向上是模棱两可的。我认为它很难意识到什么应该放在什么旁边,这就是为什么它认为它在水平方向上是模棱两可的。而且我认为将粉红色条放置在紫色或红色视图下方 20 分的位置并不合适,这就是它认为它在垂直方向上模棱两可的原因。谁能证实或否认这些怀疑?或者建议一种解决方法?当我最后运行它时,我得到了这个(我将滚动视图的背景设置为黄色,这在故事板屏幕截图中是看不到的):

在此处输入图像描述

4

2 回答 2

9

垂直模糊

好的,我想我已经解决了垂直模棱两可的部分。我在粉色和紫色视图之间添加了两个垂直约束,在粉色和红色视图之间添加了两个垂直约束。对于每一对,第一个约束是它们之间的间距必须 > 20 pts,并且它具有 1000 优先级。第二个约束是间距 = 20 pts,但它只有 800 优先级。

例如,如果紫色视图的底部最终低于红色视图的底部(就像在我的第一个屏幕截图中一样),Xcode 应该尝试将粉色和红色视图之间的垂直距离设置为 20,但它将意识到这与紫色和粉红色之间的空间 >= 20 的条件相冲突。由于 >= 约束具有更高的优先级,因此将忽略 = 约束。现在,当 Xcode 查看紫色和粉红色视图之间的间距为 = 20 的约束时,它会检查粉红色和红色必须至少分开 20 的约束。由于红色视图的底部高于在紫色视图的底部,红色和粉色之间的 >= 20 约束仍然通过。

所以 TL;DR,您可以设置一个视图,使其在多个视图中的最极端处具有给定值 (x) 的间距,方法是给它一个具有 1000 优先级的 >= x 约束并给它一个具有 <1000 的 = x 约束您正在考虑的每个视图的优先级 - 我的垂直歧义问题已经解决。对于所有 4 个视图的水平歧义,我还没有解决方案。

水平模糊

好的,我现在也修复了水平方向模糊的部分。它归结为滚动视图(以及表视图)中的约束与任何其他类型的视图中的约束不同。这是分步的样子。

  • 放置UIScrollView
  • 将 aUIView放入UIScrollView作为contentView该滚动视图的“”
  • 添加约束以将其固定contentView到滚动视图的所有 4 个角并固定它widthheight(因此它和它的超级视图之间有 6 个约束contentView- 比平时多 2 个)。请注意,widthheight可以固定到比正常屏幕尺寸大得多的地方,这可能是您开始使用滚动视图的原因。
  • UIScrollView在( UIButtons,等中添加您想要的所有其他视图UILabels- 我只是假设UILabel从这里开始,所以我不必输入那么多,但任何类型的UIView子类都可以)作为contentView,不直接作为子视图UIScrollView

使用此设置,为UILabel其父视图提供约束的 s 将约束为contentView具有定义大小的 ,因此没有什么是模棱两可的。

或者,如果您想修复UILabels 的大小(或动态计算它们,具体取决于您的应用程序的功能)并让contentView扩展来保存它们:

  • 放置UIScrollView
  • 将 aUIView放入UIScrollView作为contentView该滚动视图的“”
  • 添加约束以将其固定contentView到滚动视图的所有 4 个角并固定它widthheight
  • 为(假设我们命名它)width上的约束创建一个出口contentViewcontentViewWidthConstraint
  • 放置UILabels
  • 修复UILabels的大小
  • 为swidth上的约束创建一个出口UILabel

然后在代码中viewWillLayoutSubviews

  • 将所有UILabels 的宽度以及它们之间所需的任何间隙相加(作为 a CGFloat,我将其称为totalWidth
  • contentViewWidthConstraint.constant = totalWidth

你很高兴去!请注意,我假设您在此示例的大部分内容中都设置了宽度,但它应该同样适用于高度。

于 2013-10-09T16:14:55.980 回答
5

问题是两个视图的许多不同宽度将满足您设置的约束。这是两个示例(我绘制了垂直堆叠的形状,以便更容易看到重叠示例):

歧义示例

您可以添加值为 0 的水平空间约束。

截屏

于 2013-10-08T17:15:20.423 回答