ChatGPT解决这个技术问题 Extra ChatGPT

什么是 Xcode 6 中情节提要中的“限制到边距”

我正在使用自动布局和约束,发现 Xcode 6 中有一个 Constrain to margins 选项,该选项在 Xcode 5 中不存在,默认情况下已选中。

我创建了一个测试项目,然后在 ViewController 上添加了一个 UITableView,框架设置为与视图相同的大小并添加了约束

Xcode 6 即使 tableview 与视图具有相同的框架 Xcode 建议添加 -16 作为约束,而 Xcode 5 建议添加间距 0,您也可以在此处看到。

https://i.stack.imgur.com/aZF5T.png

现在,当您取消选中“Constrain to margin”选项时,它的行为与 Xcode 5 相同,并建议添加 0 作为约束

https://i.stack.imgur.com/ncu1i.png

另外,我发现一旦我添加约束到边距检查,我不再能够在 Xcode 5 中打开情节提要文件,所以这绝对是 Xcode 6 中的新东西

希望我能够正确解释我的问题。我想了解“限制边距”的实际作用以及何时应该和不应该使用它。如果这是非常简单和明显的事情,我深表歉意。

编辑

我在 discussion here 中发现了一些关于布局边距的内容,我想知道它是否与此有关。

无需道歉——这根本不明显。
+1 不用道歉,我也想问这个问题。顺便说一句:要在 Xcode5 中打开情节提要,请查看:stackoverflow.com/a/25298909/529243
这是我找到的最接近解释的东西:stackoverflow.com/questions/25275901/…
如何禁用此功能?
是的,这才是真正的痛苦。我一直无法弄清楚如何永久取消选中它。

C
Community

我完全不明白为什么人们会抱怨“Margins 会导致 iOS 8 之前的任何东西彻底崩溃”。

在 xib 文件或情节提要中设置相对于边距的约束不会使您的应用程序在 iOS7 上崩溃,并且只要您不触摸 UIView.layoutMargins 和 UIView,它也不会在您的 iOS7 设备上产生 UI 差异。在您的代码中保留SuperviewLayoutMargins 属性。

iOS8中的边距是什么

布局边距表示在布局子视图时布局系统可以使用的 UIView interior 周围的填充 - 以确保在视图边缘和子视图之间留有间隙。在这方面,它非常类似于 CSS 中与块相关的填充属性。

https://dl.dropboxusercontent.com/s/8y3tavoeoritz19/Screen%20Shot%202558-02-23%20at%204.04.17%20PM.png?dl=0

默认情况下,UIView 每边的布局边距为 8 磅,这不能在 Interface Builder 中更改。但是,通过在代码中设置 UIView.layoutMargins 属性(仅在 iOS8 上可用),您可以调整这些值。

您可以使用 Editor > Canvas > Show Layout Rectangles 让 IB 显示边距:

边距可用于帮助布局视图和子视图。默认情况下,每个 UIView 都带有边距,但它们仅在您设置与边距相关的约束时才会影响视图放置。

如何使用边距

在 Interface Builder 中使用边距的唯一方法是在配置约束时检查相对于边距选项。这就是您在布置视图时将约束指示为使用边距而不是边缘的方式。

https://dl.dropboxusercontent.com/s/jea4s3m8zey4q6l/Screen%20Shot%202558-02-23%20at%204.57.25%20PM.png?dl=0

让我们看一下在视图及其子视图之间设置前导约束的四种不同方法。对于每个约束,我们都会查看描述的第一个关联将是子视图的前导,第二个将是父视图的前导。您要密切注意的是每个约束端的相对于边距选项的选中和取消选中状态,因为它定义了约束是绑定到边距还是视图边缘。

第一项(取消选中),第二项(选中):在这种情况下,我们声明子视图的左边缘应与父视图的左边距对齐(如图所示)。

https://dl.dropboxusercontent.com/s/r1bnsky2mahq9mw/Screen%20Shot%202558-02-23%20at%205.13.32%20PM.png?dl=0

第一项(取消选中),第二项(取消选中):都使用边缘,而不是边距。在这种情况下,我们声明子视图的左边缘应该与父视图的左边缘对齐。

https://dl.dropboxusercontent.com/s/ncj55zl5mz78r4z/Screen%20Shot%202558-02-23%20at%205.18.30%20PM.png?dl=0

第一项(选中),第二项(取消选中):在这种情况下,我们声明子视图的左边距应该与父视图的左边缘对齐。这种布局实际上使子视图与父视图重叠。

https://dl.dropboxusercontent.com/s/cc6a8gaxnz18cbu/Screen%20Shot%202558-02-23%20at%205.23.36%20PM.png?dl=0

第一项(检查),第二项(检查)。这实际上与案例 2 具有相同的效果,因为 subview 和 superview 具有相同的默认边距。我们声明子视图的左边距应该与父视图的左边距对齐。

https://dl.dropboxusercontent.com/s/ncj55zl5mz78r4z/Screen%20Shot%202558-02-23%20at%205.18.30%20PM.png?dl=0

边距有什么好处

如果您决定使用边距,此新功能 (iOS8) 只会影响 UI 开发。

通过使用边距,您可以通过更改单个属性的值来调整与共享父视图共享公共关系的多个子视图的位置。这明显优于使用固定值设置所有关联的约束,因为如果您需要更新所有间距,而不是一个一个地更改每个值,您可以通过使用单行更新超级视图的边距来同时修改所有相关的位置像这样的代码:

self.rootView.layoutMargins = UIEdgeInsetsMake(0, 50, 0, 0);

为了说明这个好处,在以下情况下,所有子视图的左边缘都与其父视图的左边距对齐。因此,更改 superview 的左边距会同时影响所有子视图。

https://dl.dropboxusercontent.com/s/ggmjfujf1vm9by0/Screen%20Shot%202558-02-23%20at%205.47.24%20PM.png?dl=0


感谢您的详细解释。我将此标记为已接受的答案,因为这很好地解释了事情。
谢谢@Bhumit,希望这个答案有所帮助。
“我完全不明白人们为什么抱怨”。好吧,也许最后一个测试版的行为改变了,我还没有检查过。但至少在几个月前,即使您没有尝试在代码中设置 layoutMargins,它也确实会导致崩溃。
值得指出的是,在添加新约束时,较新版本的 Xcode 允许您取消选中设置相同“相对于边距”标志的“约束到边距”框。这很有用,因为它可以节省几次点击!顺便说一句,答案很好,解释得很好,图片很有帮助。
我注意到图片托管在 Dropbox 上。在 SO 上托管图像不是更好吗?
K
KPM

在 iOS 8 中,您现在可以选择相对于超级视图边界的预定义边距来定义约束,而不是超级视图本身的边界。是的,它与您在文档中指出的布局边距完全相关。一个优点是您可以动态地重新定义您的边距,或者为每种设备以不同的方式重新定义边距,并且布局将相应地更新而无需修改约束。

何时使用它:当您想利用这种新的灵活性时。

何时不使用它:适用于任何在 iOS 7 或更低版本上运行的应用程序。


如果默认情况下没有启用它,但在 iOS 8 之前的任何东西上会导致彻底崩溃,这将是一个很好的功能。
K
Kyle Robson

UIView 上的属性是:layoutMargins。请参阅 Apple Docs。基本上,如果布局边距为 8,8,8,8(默认值),则前导空间为 0 到容器边距的约束的 x 位置将为 8。请注意,这仅适用于 iOS8 或更高版本。< /强>

对于不希望他们的约束进入容器边距的每个人:

CTRL+单击+拖动以显示约束创建弹出窗口。

如果菜单显示默认创建对边距的约束,请按住 option/alt 以允许对容器而不是容器边距进行约束。

现在它将显示创建约束而不是边距的选项。这在我的使用中要快得多。


这可能是我在那里找到的最好的解决方案。取消选中“限制到边距”并不总是有效,而且感觉有点太神奇了。太棒了。
为什么默认不是10pt?
Apple 有根据可用性研究选择长度和尺寸的历史,而不是通过选择我们阅读代码可能更喜欢的数字。例如,许多事物的默认高度是 44 或 35 pt。 @ZaBlanc
默认情况下,当我在没有边距的情节提要上添加约束时,这是完美的解决方案。谢谢!