根据子视图大小调整 Window 并包含 NSView

Resize Window and contained NSView based on subviews size

对于 MacOS 应用程序,我有一个 Window,其中包含一个 NSView;在该视图中,我想添加一个具有恒定大小和高度的子视图。

当通过 [myView addSubview:mySubview] 以编程方式加载子视图时,我希望承载子视图的 NSView *myView 改变大小以适应子视图,并且 window 改变相应的大小;这样 Window 内部的 NSView 边缘与 Window 中的周围环境保持相同的距离。我如何最有效地实现这一点,以及我必须在 IB 中指定哪些属性才能使其发挥作用?我是否必须手动以编程方式调整 myView 和 Window 的大小,或者我能否以更漂亮的方式实现此目的?

有多种方法可以实现这一点。
一个简单的方法是设置 autoresizingMask 您想要的值。 您在 Interface Builder 中看到的掩码由预定义的数字 (NSAutoresizingMaskOptions) 表示,您将结合位运算

view.autoresizingMask = NSViewMaxXMargin | NSViewMaxYMargin;

这类似于 IB 的这个屏幕截图中的自动调整大小

Layout Translates Mask Into Constraints 上的复选标记必须在 IB 中或以编程方式进行,以便将它们用作约束。

view.translatesAutoresizingMaskIntoConstraints = YES;

当视图用
-initWithFrame: 和给定的 frame 或在IB 在创建实例并通过 -initWithCoder: 初始化 UI 元素时。

请注意,这不会阻止 IB 的自动布局机制警告您您想要的坐标、大小和约束可能与约束冲突。

根据 @Willeke 的建议,我需要了解和应用自动版式。为了使其在 IB 中工作,我将子视图的 autoresizingMask 设置为坚持所有边并自动调整宽度和高度。尽管它可以完全在 IB 中完成,但我认为以编程方式这将是

subview.autoresizingMask = NSViewWidthSizable | NSViewHeightSizeable;

正如 @Ol Sen 在他的回答中所指出的,Translates Mask Into Constraints 也必须被激活。

为了按照开头 post 中的描述以编程方式添加子视图中的元素,我依赖嵌套堆栈视图并调整它们的大小,而不是调整父视图的大小。

剩下的唯一问题是在添加之前正确调整子视图的框架以匹配父视图。如果省略此步骤,则子视图的自动调整大小掩码在添加时将转换为约束,这将导致正确的调整大小行为,但边距错误。基本代码如下所示:

MySubViewController *subViewController = [[MySubViewController alloc] init];
subViewController.view.frame = superView.bounds; // Correct the margins
[superView addSubview:subViewController.view];