如何以编程方式关闭视图层次结构的自动布局?

How to turn off AutoLayout for a view hierarchy programmatically?

我已经创建了一个单独的框架来容纳我的视图层次结构,应该启用自动布局。为了实现这一点,我在 Interface Builder 中(在故事板上)取消勾选 "Use Auto Layout" 复选框。

我将以下操作添加到此基本视图中的按钮,以测试在视图层次结构(视图 + 按钮)上没有生成任何约束:

    @IBAction func buttonPressed(sender:AnyObject?){
    println(self.view.constraints)
    println(self.view.subviews[0].constraints)
}

然后我将上面的框架导入到一个新的 Cocoa 应用程序中,该应用程序确实启用了 AutoLayout 并在容器视图控制器中重新使用上面框架中的视图控制器。按下按钮时,结果如下:

[]
[<NSContentSizeLayoutConstraint:0x6080000a7da0 H:
[NSButton:0x600000140e70'Button'(46)] Hug:250 CompressionResistance:750>,
<NSContentSizeLayoutConstraint:0x6080000ad6e0
V:NSButton:0x600000140e70'Button'(21)] Hug:250 CompressionResistance:750>]

问题:

  1. 以上是否意味着我的按钮以某种方式获得了一些约束?
  2. 他们是另一种(更具编程性的方式)在视图层次结构中关闭 AutoLayout - 在这种情况下,除了关闭约束之外,我不会将故事板用于任何其他用途。

更多信息:

translatesAutoResizingMasksIntoConstraints 视图和按钮都设置为 false - 为了安全起见。

我也试过 运行 Instruments/AutoLayout 但是当我的程序启动时它崩溃了。崩溃报告中的堆栈跟踪显示它在崩溃时正忙于与 AutoLayout 相关的调用!

编辑

我想在我的视图层次结构的一部分中禁用 AutoLayout,只是为了在滚动具有复杂布局的文档时获得性能优势。

我的 scrollView 正在一个类似于 tableView 的控件上执行滚动(它是一个电子表格网格)。我的方法是在向右滚动时从左侧移动(又名重新布局)单元格等......我发现当我滚动得非常快时会出现滞后效应(在角落里表现为 flashing/flickering屏幕),细胞无法足够快地移动。他们当然会在 500 毫秒到 1000 毫秒左右之后赶上,但它看起来并没有达到应有的水平。

使用 Instruments(时间分析器)我还可以看到 "layout & display" 占用了大部分繁忙时间,布局与显示差不多。我还在没有将内容加载到单元格中的情况下进行了测试,以了解布局是否不够快(事实并非如此)。

更有趣的是,查看 Instruments (AutoLayout),我当然可以看到它在滚动期间非常忙于处理约束,但我不能说这是否一定很糟糕。

我的想法是,对于像这样的复杂(按移动部件的数量)view/control,AutoLayout 可能需要更长的时间来数学解决约束集问题,而不是我直接告诉它所花费的时间新框架是什么。

根据 window 启用或禁用自动布局,不适用于视图层次结构的部分。如果 window 中的任何内容使用自动布局,那么整个 window 都会使用。也就是说,如果任何东西为 window 的层次结构中的任何视图添加或激活约束,或者任何视图的 class 将 +requiresConstraintBasedLayout 覆盖为 return true,则 window 将使用自动布局。

请注意,系统视图甚至主题框架视图(绘制标题栏的内容)都可以在您不知情的情况下使用自动布局。即使 window 中的视图在 OS 的当前版本中没有使用自动布局,它们也可以在未来的任何版本中更改为自动布局。

所以:不,你不能禁用某些自动布局。

translatesAutoResizingMasksIntoConstraints 设置为 false 不会避免打开自动布局。这只是意味着如果自动布局 is 打开(通过其他方式),这些视图将被错误地布局(因为它们没有从其他任何地方获得约束)。通常,将 translatesAutoResizingMasksIntoConstraints 设置为 false 仅由选择 in 自动布局的代码完成。

translatesAutoResizingMasksIntoConstraints 默认为 true 允许系统在 windows 中透明地启用自动布局,这些应用并非设计为使用自动布局而不破坏其行为。

您如何确定滚动时自动布局与性能问题有关?


更新:

减轻网格视图的自动布局对性能造成的任何影响的一种可能方法是关闭单元格视图的 translatesAutoResizingMasksIntoConstraints(正如我所说的那样是个坏主意),然后手动关闭将它们的框架设置为覆盖 -layout。我认为这是合法的。

您可能还会在将它们添加到父视图时设置它们的框架,但这还不够。如果您不在 -layout 覆盖中放置它们,自动布局可能会将它们的框架归零。