控件的frameForAlignmentRect上的自动布局setFrameSize

时间:2015-02-26 02:54:29

标签: ios objective-c autolayout

在WWDC 2012 Session 228视频“掌握自动布局的最佳实践”中,它将intrinsicContentSize解释为更好的sizeToFit并继续此示例:

NSRect alignmentRect = (NSRect){NSZeroPoint, [control intrinsicContentSize]};
[control setFrameSize: [control frameForAlignmentRect:alignmentRect].size];

执行上述代码的目的是什么?

1 个答案:

答案 0 :(得分:2)

视频以“#34; intrinsicContentSize开头,也适用于弹簧和支柱"。因此,首先要了解的是,这部分是关于您使用自动布局的时候。

这很好,因为在使用自动布局时不应使用-setFrameSize:

因此,他们所说的是,您可以通过从intrinsicContentSize开始而不是使用sizeToFit来更准确地确定控件的良好框架。对于许多控件,如果您拨打-sizeToFit,他们会使自己更大,以满足其内容所需的大小(例如,弹出按钮菜单中的标签或菜单项的标题) )。他们解释说,即使OS X主题或艺术作品发生了变化,他们也无法使sizeToFit更好地工作,因为二进制兼容性问题。

intrinsicContentSize是一个更好的工具,可以使控件达到适合其内容所需的大小,而不是更大。这是正确的,因为intrinsicContentSize没有二进制兼容性问题,即使主题和插图发生变化,也会继续如此。

然而,内在大小是对照的对齐矩形。对于视图,有框架,然后是对齐矩形。框架必须足够大,以包含视图所做的所有绘图,甚至是那些看到它的人会认为是主要形状或大小的东西。对齐矩形是自动布局系统应与其对齐视图的边界。例如,如果一个视图有一个发光,那么发光必须在视图的框架内,但应该在它的对齐矩形之外(因为其他视图不应该与发光的极限对齐)。

他们必须将内在内容大小从对齐大小转换为帧大小。但是,从对齐转换为帧的唯一机制是处理矩形(NSRect s),而不是大小(NSSize s)。因此,他们构造一个适当大小的矩形,转换它,然后检查生成的矩形的大小。

他们创建一个NSRect,其来源任意位于(0,0)并且控件的大小为intrinsicContentSize(NSRect){NSZeroPoint, [control intrinsicContentSize]}是什么。那是使用C "compound literal" syntax制作NSRect。注意,这里假设控件具有水平和垂直两个维度的固有内容大小。并非所有控件都可以。有些人在一个或两个维度中使用NSViewNoInstrinsicMetric / UIViewNoIntrinsicMetric,这项技术不会对这些控件起作用,至少在没有一些调整的情况下也是如此。

然后,他们将矩形从对齐矩形转换为帧矩形。他们必须要求控件进行此转换。对于某些控件,对齐矩形和框架可能相等;对于其他人来说,可能存在显着差异。只有该控件的实现知道它的对齐rect和它的帧应该如何相关。因此,您必须让控件为您进行转换。这是[control frameForAlignmentRect:alignmentRect]给你的东西。

现在你有一个框架矩形。起源基本上是任意的,因为你从NSZeroPoint开始。你不想control.frame = <the computed frame>。这会将控件移到任意原点,你不想这样做。您只想设置控件的大小,仅保留其原点。因此,您从计算的帧rect中提取大小。这是.size访问权限[control frameForAlignmentRect:alignmentRect].size中的内容。

最后,既然你有一个新的控件大小,你可以在控件上设置它。也就是说,将它传递给控件上的-setFrameSize:方法。现在,控件的大小与其内容相符但不大。