我如何让窗口的contentView“拥抱”它的子视图

时间:2012-05-02 14:13:24

标签: cocoa nsview nsviewcontroller autolayout

this question类似,我有一个NSView,它是NSWindow的contentView,它包含几个垂直堆叠的子视图。其中一些是固定大小的,其中一些可以使用公开按钮进行扩展或折叠。

我希望实现一种“手风琴”效果,其中扩展或折叠其中一个子视图会使其他所有内容调整并相应地调整超视图和窗口的大小。

通过使用自动布局设置正确的约束条件,我真的应该能够实现这一目标,现在让它做好初始布局。但我无法弄清楚如何设置约束,以便superview自动重新调整尺寸以拥抱子视图。

上面链接的问题中的OP从来没有得到答案,并提供了自己的解决方案,就像我开始独立实现的那个,但我想我会再次把它扔出去,以防有任何汽车布局专家知道一招似乎应该有一种方法可以让superview通过利用自动布局来拥抱子视图,而无需手动计算子视图的大小并手动重置超级视图的大小。

谁知道怎么做?

2 个答案:

答案 0 :(得分:2)

Autolayout很酷而且很全面。和奥术。

我努力了,但无法想出一套可以做我想做的约束。在我看来,如果你在一个超视图中垂直堆叠一些NSView并设置约束,以便将顶部子视图固定到超视图的顶部并沿着子视图堆栈向下,将每个顶部子视图固定到底部边缘。上面的那个,然后最后你将最后一个子视图的下边缘固定到superview的下边缘,然后以编程方式调整一个或多个子视图的大小,它应该能够拉出或向下推到superview的底部让它拥抱它的子视图。

除了最后一件外,一切都按预期工作。当您尝试将底部子视图固定到超级视图的底部时,自动布局无法满足所有约束。似乎调整超级视图的大小以满足约束不在算法中。要么我错过了一些需要设置的其他约束。

当我在讨论主题时,看着调试器,看起来窗口的contentView和窗口框架之间存在不可设置的约束。我有点想知道是否能够解决这些限制会使原始方案有效。

无论如何,我确实提出了一个使用autolayout的解决方案,它非常接近我希望autolayout会做的事情,因为所有必要的是继承NSView并将几行代码放入intrinsicSize方法然后使用超级视图的子类。

我创建了一个xcode项目,它包含我的可折叠视图基类和github上整个事物的工作演示。

答案 1 :(得分:0)

我可以确认,在像你这样的情况下,Xcode自行安装的自动约束会破坏布局。例如,如果您的变量垂直视图没有明确的约束,那么IB可能会添加一个自动变量以使布局明确无误。稍后,当您尝试通过在其上安装另一个约束来更改该视图的大小时,您将收到自动布局错误。

可能的解决方案之一(没有实现-intrinsicContentSize和/或其他子类)是在IB中查找所有自动约束,这可能会干扰您的布局并尝试在较低优先级的位置设置显式的约束。但这并不是一直有效。

另一个残酷的解决方案是删除-awakeFromNib中的所有约束,然后只设置您需要的约束。当然,您可以尝试仅以编程方式删除那些阻碍您的约束,但这并不健全,因为下次更改.xib中的某些内容时,问题可能会重新出现在完全不同的位置。

通常情况下,我必须做两件事才能让一切正常运作。