Interface Builder会逐步降低故事板,调整大小和重新放置视图


71

我们有许多不同的开发人员参与的iOS应用程序。我仍然注意到的一个问题是,情节提要中的视图将偏离其放置位置或调整其大小以使其更小,而这些尺寸在最初适合文本的标签上,当所有标签突然截断了他们的文字。

我注意到,当开发人员未直接对情节提要进行任何编辑时,视图的这些降级会出现在对Git存储库的提交中。他们可能已经在Interface Builder中查看了情节提要,但未对情节提要进行任何实际更改。尽管如此,更改仍随其工作一起保存并提交。

当我在负责提交之前和之后在故事板文件之间进行文本比较时,我会看到一些小的变化以查看框架,例如:

<rect key="frame" x="203" y="8" width="362" height="29"/>
                             |
                             V
<rect key="frame" x="203" y="7.5" width="362" height="29"/>

<rect key="frame" x="446.00000170260091" y="7" width="302" height="30"/>
                      |
                      V
<rect key="frame" x="446" y="7" width="302" height="30"/>

<rect key="frame" x="364" y="3" width="200" height="38"/>
                      |
                      V
<rect key="frame" x="363" y="3" width="200" height="38"/>

<rect key="frame" x="284" y="7" width="97" height="30"/>
                      |                |
                      V                V
<rect key="frame" x="283" y="7" width="96" height="30"/>

<rect key="frame" x="384.00001078580522" y="7" width="101" height="30"/>
                      |                                |
                      V                                V
<rect key="frame" x="383.00000530853856" y="7" width="100" height="30"/>

在大多数情况下,框架尺寸的数字仅发生少量变化,或者整数值改变1,或者浮点值被截断,或者小数部分改变。

在其他时候,这些值会发生一些变化,例如:

<rect key="frame" x="334" y="3" width="200" height="38"/>
                      |
                      V
<rect key="frame" x="331" y="3" width="200" height="38"/>

<rect key="frame" x="251" y="7" width="223" height="30"/>
                                        |
                                        V
<rect key="frame" x="251" y="7" width="220" height="30"/>

<rect key="frame" x="478" y="3" width="274" height="38"/>
                      |                 |
                      V                 V
<rect key="frame" x="475" y="3" width="276" height="38"/>

请注意,当开发人员不打算对情节提要进行单个更改时,所有这些示例框架更改均来自同一示例提交。该文件的两个版本之间在XML上有269个差异,所有这些都是帧大小或位置的这些细微变化。情节提要XML约为9000行。

看来这个问题可能与IB使用浮点数和舍入误差有关,并且被几个像素抵消的差异可能是在多次打开,解析和重新序列化的一段时间内这些舍入误差的汇总数据。

不过,这只是一个理论,因为我无法查明不必要更改的确切原因。通常,提交根本不会对框架进行任何重大更改,而只是微不足道的浮点更改,例如446.00000055262581-> 446.00000112002783。但是,当发生严重变化时,它们似乎会大量发生。

同一开发人员也使用相同版本的Xcode和Interface Builder也进行更改之间的提交。在此示例提交数据的地方,例如,文档标记<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" initialViewController="JAD-vj-VfC">位于情节提要文件的两个版本中。

除了确保不要对情节提要文件进行微不足道或意外更改之外,我还想缩小导致我们的情节提要视图发生这些不必要更改的原因。如果这是我们可以避免的导致问题的原因,那么我们可以知道原因。

更新: 正如Tim所指出的那样,此问题似乎是在视网膜显示器上使用Interface Builder时引起的。引起此问题的所有开发人员都拥有视网膜MacBook Pro。我们这些没有视网膜显示的人没有遇到过这个问题。


3
Xcode 9.4.1仍然残破。每次打开情节提要时,都会产生数百个差异。
Daniel Asher

3
Xcode 11.3.1-错误仍然存​​在。2014-2020(...)打开情节提要板后,Xcode仍会产生大量差异。
阿纳斯塔西娅

Answers:


24

这个谜题中最有趣的线索是,当您在Retina显示器上打开同一故事板而不是非视网膜显示器时,这似乎特别糟糕。

最初,我是在4k iMac和视网膜前的Macbook Pro之间来回走动的,并且进行了大量更改(每次更改约300行)。

然后,我只是将xcode窗口从主监视器(4k / retina)拖到第二个监视器(2560x1440,非视网膜)-并且,当窗口大小相同时,xcode调整了所有元素的大小,并抱怨约50个位置错误的视图。我将其移回视网膜显示器,大约一半的“错位”错误消失了,但一半仍然存在。如您建议的那样,重新缩放会降低基础数据的质量。

如果您有多个开发人员在同一个文件上工作,那么这势必会经常发生。

解决方案?这很可能在Apple上都可以纠正-我没有遇到任何可以减轻它的设置。


Pradeep K找到了让Xcode忽略Retina显示模式的设置stackoverflow.com/a/36124980/2064473,尽管他指出,这克服了使用Retina显示的问题。我之所以禁用此设置,是因为无论如何我大部分都是在外部显示器上进行开发的。
马丁

8

这似乎是与Interface Builder的CGFloat值序列化有关的错误。视图框架的大小和位置值是浮点数。但是它们的值始终是整数。内部图形操作要求它们为浮点,以便转换数学工作,但是所有内容始终以舍入整数点值表示。

将这些浮点值序列化到情节提要XML时,IB经常将值序列化为整数,但有时也将其序列化为浮点数。我不确定为什么会决定这样做,但是这种情况并不常见。在上面的示例框架中,其中3个值最终为浮点数,而其他值为整数。

在我的示例中也可以看到,通常浮点表示将更改为序列化为整数。我认为这是发现错误的地方。

我注意到视图框架的变化方式是一件事,它们倾向于向左移动或缩小尺寸。因此,值通常会越来越小。您可以在我提供的示例中看到,这是大多数情况。

浮点数不能精确地表示整数值,但可以精确到小数点后几位。因此,尽管有时整数在我的示例中表示为略高于整数(即384.00001078580522),但其他整数则表示为略低于整数。这是IB更改框架的示例:

<rect key="frame" x="457" y="7" width="291" height="30"/>
                      |
                      V
<rect key="frame" x="456.99999985252464" y="7" width="291" height="30"/>

尽管此特定更改似乎并未直接修改框架的值。这两个数字基本上等于457。我认为发生的情况是,再次打开情节提要时重新解析此XML时,它可能会截断456.99999985252464值并将其读取为456。这将导致这些值逐渐获得缩小,缩小尺寸或将框架的位置向左或向上移动。

当然,这只是一个理论,并没有给出Interface Builder为什么这样做的原因。自从最近的Xcode 6版本以来,它似乎已经开始了。而且,它并没有说明在一个示例中它是如何从8变为7.5的,甚至在我的上一个示例中也没有解释它是如何从274变为276的。但是在大多数情况下,大多数变化趋向于向下。

我正在向Apple提交错误,以便对此进行调查。


感谢Jeff冗长的解释,这也发生在我们身上。您有什么办法避免这种情况吗?
celiker 2015年

1
@celiker正如Tim所指出的那样,这似乎与在视网膜显示器上使用Interface Builder有关。我们导致问题的所有开发人员都具有视网膜显示器,而我们没有视网膜显示器的开发人员都没有问题。内部实现(解析和重写XML)似乎无法正确处理像素精度。因此,在Apple修复此错误之前,避免在视网膜显示器上使用IB是目前唯一的解决方法。
杰夫·洛克哈特

Xcode 9.1仍然让我发疯……您是否提交了错误?
塞巴斯蒂安

3

我可能会对这个问题有一个答案。在低分辨率模式下打开应用程序的鲜为人知的功能。我们最近遇到了类似的问题,其中当分隔线设置为默认值或单个时,表格视图单元格的内容视图的高度额外增加了0.5。如果将其设置为“无”,则不存在此问题。步骤1.将默认的TVC拖到情节提要。检查表视图单元格的内容视图的高度。它将是43.5。2.将表格视图的分隔线设置为“无”。单元格的内容视图更改为44。

现在,退出Xcode并在Finder“获取信息”窗口中为Xcode应用程序设置“以低分辨率打开”。现在,如果您按照上述相同的步骤进行操作,它将显示表格视图单元格的内容视图的高度为43。

当有不同的团队成员在视网膜和非视网膜显示器上工作时,您只需将情节提要文件修改为已修改,仅因为您在视网膜显示中打开了情节提要。一种解决方法是打开“低分辨率打开”模式并工作。但是,这样做虽然达到了视网膜显示的目的,但即使您未进行任何更改,也比将情节提要板标记为已修改更好。


在低分辨率模式下打开Xcode 8.2.1,然后打开情节提要文件时,我仍然看到0.5的增量。
sethfri
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.