【问题标题】:How can I turn Cocoa Auto Layout off for subviews of a NSView programmatically?如何以编程方式为 NSView 的子视图关闭 Cocoa 自动布局?
【发布时间】:2016-03-20 08:15:49
【问题描述】:

我查看了其他类似的问题,但没有一个解决真正以编程方式绕过自动布局以获取 NSView 的子视图的问题。

我需要告诉自动布局不要布局特定NSView 的子视图。我试过覆盖layout(),但这只会生成一个警告,并且没有约束的子视图(我已经在它上面设置了translatesAutoresizingMaskIntoConstraints = false,因为我不希望自动生成任何约束或以其他方式)得到无论如何,它的框架设置为全零[x=0, y=0, width=0, height=0]。我很难相信没有办法告诉 Auto Layout 不要布局视图。 translatesAutoresizingMaskIntoConstraints = true 不是我想要的,因为我想为视图的所有子视图完全禁用自动布局。我有两种情况需要这个:

  1. 一个笔记应用程序,用户可以在其中创建和定位基本几何形状和文本视图。这些都是NSView 子类。我当然可以使用约束并对其进行操作,但是不应该以任何方式自适应的视图有什么意义呢?
  2. 一个数学应用程序,我使用自动布局将数学布局在不同的行上。我想暂时关闭未编辑的行的自动布局,因为当您添加更多行和数学对象时,自动布局计算开始使应用程序逐渐变得更加无响应。由于唯一需要布局计算的是用户正在编辑的行,因此可以通过关闭其他行的自动布局来优化该过程。

【问题讨论】:

  • 您为笔记应用描述描述的方法不是最佳的。撇开文本视图不谈,这类应用程序通常只有一个 NSView 视图(画布)。几何形状只是贝塞尔路径(NSBezierPath 实例),在用户拖动它们时会重复重绘。如果您想了解这是如何完成的,请查看 Apple 的 Sketch 演示应用程序(它还向您展示了如何创建可以在画布内移动的文本)。
  • 谢谢保罗。我看过 Sketch 演示,也考虑过这种方法,但出于各种原因,我决定采用 NSView-per-object 方法。与几乎所有事情一样,每个决定都有利弊。

标签: macos cocoa autolayout


【解决方案1】:

没有办法做你想做的事。

自动布局是为整个窗口打开或关闭,而不是单个视图。如果窗口中的任何视图添加了约束或属于+requiresConstraintBasedLayout 方法返回true 的类,则窗口使用自动布局。

如果您想使用旧的视图定位方式,通过设置其框架和自动调整大小的掩码,那么您希望translatesAutoresizingMaskIntoConstraints 为真。事实上,这正是以编程方式创建的视图的默认设置,正是为了向后兼容自动布局不感知代码,以便在使用自动布局的窗口中运行。您关闭它的理由完全是倒退。

只需离开或打开translatesAutoresizingMaskIntoConstraints 并让您的代码负责将视图的框架设置为所需的任何内容。确保也根据需要设置视图的autoresizingMask,也许设置为NSViewNotSizable。您通常需要在持续时间内停用视图上的任何其他约束。

如果您需要为整个视图子层次结构执行此操作,那么您将不得不这样做——启用translatesAutoresizingMaskIntoConstraints 并设置框架和autoresizingMask——为整个子层次结构。但是,这对我来说似乎不是一个合理的方法。

【讨论】:

  • 谢谢肯。这就是我害怕的。自动布局似乎不是一个友好的伙伴;o)我也尝试使用“translatesAutoresizingMaskIntoConstraints = true”,但如果框架设置为负宽度或高度,它会引发异常。我允许这样做是因为当用户可以通过拖动在任何方向上绘制矩形时,它会使数学变得更容易。然后我只是在用户完成后标准化框架。使用 Auto Layout 完成所有这些操作会无缘无故地让事情变得更加复杂。在数学应用程序中,我真的需要以某种方式优化自动布局过程。
猜你喜欢
  • 2015-05-21
  • 2018-07-22
  • 2013-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多