我的应用程序使用“自动布局”来创建一个界面,该界面包括一个2:1容器(适合屏幕尺寸),内部有两个方形框。可以在下面看到一个示例(仅左侧框可见):

旋转设备时,代码将更新约束,以将框从左到右(横向)或从上到下(纵向)定位。该代码工作得相当不错,但是在旋转之后,该接口有时会像这样结束:

如您所见,容器的背景在左下角。它的严重性有所不同(有时甚至更明显)。
我设置了一个small project来展示这个问题;它在情节提要中包括一个小的视图层次结构,在构建时便删除了所有约束。
实际约束在 ViewController.m DualVideoView.m 内部创建/更新。
这些限制对我来说似乎很准确,因此我不确定为什么首先会发生这些布局问题。
更新资料
卸下取景器(上述屏幕截图中的橙色框)可以解决布局问题;它使用成比例的宽度和高度(例如width:= superview.width * 0.9)绘制嵌入式方形框架。不过,我不确定为什么这应该成为问题。

最佳答案

尽管您的垂直约束不是问题,但我想指出的是,它们缺少video1 / video2的高度约束:

[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:_video1 attribute:NSLayoutAttributeHeight multiplier:1 constant:0]
[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:_video2 attribute:NSLayoutAttributeHeight multiplier:1 constant:0]

但是,您的水平约束看起来不错,所以我采用了DualVideoView源代码,并围绕它创建了一个最小的应用程序(source code at codepad.org),以重现该问题。不幸的是,最小的应用程序并没有显示出您看到的那些空白,因此,除非您可以提供更多详细信息,否则我将只能猜测。与往常一样,您最有帮助的事情是显示一个最小但完整的代码示例,以解决这个问题-也许您可以从扩展我上面链接的示例应用程序开始。

我能想到的主要事情是,由于video1 / video2视图应该占据其superview宽度的一半,因此会出现舍入误差。

例如,如果DualVideoView实例的奇数宽度为1023,该怎么办?假设一半点是floor ed,则1023的一半宽度是511(511.5 floor ed)。 video1 / video2的总宽度为1022,因此留有1个点的差距。但是,此假设有两个问题:
  • 因为您的垂直约束不包括任何可能导致舍入错误的内容,所以它没有解释垂直间隙。
  • 假设是错误的,“自动版式”不是floor ing(也不是ceil ing),而是四舍五入。因此1023的一半宽度是512(向上舍入为511.5),这意味着,如果video1 / video2重叠,则应该没有间隙。

  • 您可能需要检查的一些事项:
  • 如果两次旋转180°(即旋转回原始位置),您是否仍能看到间隙?如果间隙消失,则问题可能不是舍入错误,而是取决于设备/接口方向的错误定位计算。
  • 如果您使用Retina显示模拟器或设备进行测试,您还能看到差距吗?可能有所不同,因为在Retina显示屏上,自动版式的舍入方式不同(它允许.5值并以.25步长舍入)。如果间隙仍然存在,并且您正在模拟器上进行测试,则使用Pixie应用程序进行测量以查看间隙是1还是2像素宽可能很有趣。
  • 如果您使用约束将video1 / video2对齐到其 super 视图的边缘而不是其中心(例如,将video1的顶部/左侧边缘与其视图的顶部/左侧边缘对齐),是否会有所不同?


  • 更新

    在GitHub示例项目中,我将问题跟踪到video1视图的白色小子视图在情节提要中存在的约束。具体来说,问题与0.9乘数有关-如果将多重乘数重置为其默认值1.0,而是使用常量(例如-20),那么所有调整大小的问题都将神奇地消失。我之所以说是“神奇”,是因为我对为什么乘数产生如此大的影响感到困惑。如果我有更多时间,将对此进行另外的检查,但是现在这是我的建议:使用恒定值而不是乘数。

    我注意到的另一件事是,大多数(但不是全部)约束都以相反的方式表示依赖关系。例如:
    [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.videoContainerView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0],
    

    此约束表示VC主视图( super 视图)的center.x取决于视频容器视图(子视图)的center.x。我发现这是一种思考 super 视图与子视图之间关系的奇怪方法,通常我会反过来思考。诚然,Auto Layout方程求解器似乎能够解决这个问题,但是我仍然建议按照自然依赖顺序编写约束。如果没有别的,它将帮助其他人更好地理解您的代码。

    更新2

    一些其他研究:
  • 布局问题仅发生在iPhone模拟器中,而不发生在iPad模拟器中
  • 如果按比例缩放的视图不是与其中心对齐,而是与其视图的顶部和左侧边缘对齐,则布局问题将消失(video1)
  • 使用调试工具constraintsAffectingLayoutForAxis来检查1)主视图,2)视频容器视图和3)video1视图(包含白色比例大小的视图)ojit_code不会揭示涉及比例大小视图的任何约束-尽管删除了该视图或以其他方式对齐,对布局
  • 有明显的影响

    特别是最后一点使我相信,约束的这种组合暴露了“自动布局”引擎中的错误。我建议您使用与您在GitHub上发布的最小示例类似的方式向Apple提交错误报告。

    10-05 22:44