2

这个问题一样,我有一个 NSView,它是 NSWindow 的 contentView,它包含几个垂直堆叠的子视图。其中一些是固定大小的,其中一些可以使用展开按钮展开或折叠。

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

看起来确实应该能够通过使用自动布局设置正确的一组约束来实现这一点,我现在可以很好地完成初始布局。但我不知道如何设置约束,以便超级视图自动调整大小以拥抱子视图。

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

有人知道怎么做吗?

4

2 回答 2

3

自动布局既酷又全面。和奥术。

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

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

当我谈到这个主题时,看着调试器,似乎在窗口的 contentView 和窗口框架之间存在不可设置的约束。我有点想知道是否能够弄乱这些约束会让原始方案发挥作用。

无论如何,我确实提出了一个使用自动布局的解决方案,它非常接近我希望自动布局能做的事情,因为所需要的只是子类化 NSView 并将几行代码放入intrinsicSize 方法,然后使用该子类超级视图。

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

于 2012-05-08T18:50:47.040 回答
0

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

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

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

通常,我必须同时做一些事情才能让一切正常工作。

于 2012-08-22T04:58:37.570 回答