macos NSView 的自动调整大小行为

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/967625/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 06:12:25  来源:igfitidea点击:

NSView's autoresizing behavior

cocoamacosnsviewautoresize

提问by EightyEight

I need to understand how NSView autoresizes it's views. I've set everything up in IB and my subviews resize nicely (when I resize my window around with a mouse). However, if I do [myMainView setFrame:]with my new frame rect, nothing happens. All of my sub-views are still the original size (even though the main view has the correct dimensions). Child's resizeWithOldSuperviewSize:gets called, but it's still not appropriately sized.

我需要了解 NSView 如何自动调整其视图的大小。我已经在 IB 中设置了所有内容,并且我的子视图大小调整得很好(当我用鼠标调整窗口大小时)。但是,如果我[myMainView setFrame:]使用我的新框架矩形,则什么也不会发生。我所有的子视图仍然是原始大小(即使主视图具有正确的尺寸)。Child'sresizeWithOldSuperviewSize:被调用,但它的大小仍然不合适。

I have a screen-full of cocoa elements on screen (screen #1), label, image, video. There's a well-defined layout for these elements. I've setup autoresizing behavior via Interface Builder that works very well. Resizing the main window resizes the elements in a satisfying manner.

我在屏幕(屏幕 #1)、标签、图像、视频上有一个充满可可元素的屏幕。这些元素有一个明确定义的布局。我已经通过 Interface Builder 设置了自动调整大小的行为,效果很好。调整主窗口的大小会以令人满意的方式调整元素的大小。

Now, the user clicks the "next" button, whereupon a second screenfull of elements (screen #2) is to be drawn. My layouts are built based on a canonical screensize (say, 800x600). But now the window is larger (or smaller) because it was resized in screen #1. So the elements are now only taking a small area in the window, instead of being appropriately sized to fill the available space. I want to scale these elements.

现在,用户单击“下一步”按钮,然后将绘制第二个屏幕元素(屏幕 #2)。我的布局是基于规范的屏幕尺寸(例如 800x600)构建的。但是现在窗口更大(或更小),因为它在屏幕 #1 中调整了大小。因此,元素现在只占用窗口中的一小部分区域,而不是适当调整大小以填充可用空间。我想缩放这些元素。

Am I misunderstanding how autoresizing works? How can I trigger the autoresize machinery underneath NSView manually?

我误解了自动调整大小的工作原理吗?如何手动触发 NSView 下的自动调整大小机制?

There are two things I can do:

我可以做两件事:

  1. Manually resize the elements based on the current screen size relative to original size. This option is not my favorite because seemingly, I'm forced to rewrite the code that's already working in NSView (the autoresizing behavior
  2. My second option is to invoke the aforementioned NSView's autoresizing magic. Documentation implies that [NSView setFrame:] will do that for me. What I've tried was, resize my content view to the original screensize (800x600), render my elements and then resize it to the current window size. Conceptually, is it not identical to manually resizing the window? It appears not to be. Again, this option is preferable because it minimizes the amount of code that has te be written and maintained.
  1. 根据当前屏幕大小相对于原始大小手动调整元素的大小。这个选项不是我最喜欢的,因为看起来,我被迫重写已经在 NSView 中工作的代码(自动调整大小行为
  2. 我的第二个选择是调用前面提到的 NSView 的自动调整大小魔法。文档暗示 [NSView setFrame:] 会为我做到这一点。我尝试过的是,将我的内容视图调整为原始屏幕大小(800x600),渲染我的元素,然后将其调整为当前窗口大小。从概念上讲,是否与手动调整窗口大小不同?似乎不是。同样,此选项更可取,因为它最大限度地减少了需要编写和维护的代码量。

采纳答案by EightyEight

Turns out my approach is correct. I was setting the frame size to an incorrect value, thus I wasn't getting the expected behavior. Doh.

事实证明我的方法是正确的。我将帧大小设置为不正确的值,因此我没有得到预期的行为。多。

回答by Nikolai Ruhe

This code

这段代码

NSView* superView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];
NSView* subView   = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];
[superView addSubview:subView];

[superView setAutoresizesSubviews:YES];
[subView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];

NSLog(@"subview's frame before resizing: %@", NSStringFromRect([subView frame]));
[superView setFrame:NSMakeRect(0, 0, 200, 100)];
NSLog(@"subview's frame after  resizing: %@", NSStringFromRect([subView frame]));

does give the expected result:

确实给出了预期的结果:

[...] subview's frame before resizing: {{0, 0}, {100, 100}}
[...] subview's frame after  resizing: {{0, 0}, {200, 100}}

Your problem is elsewhere. I expect that one of your container views is not a part of the view hierarchy of the window at the time when the resize occurs.

你的问题在别处。我希望在调整大小发生时,您的容器视图之一不是窗口视图层次结构的一部分。

A good solution for your problem might be the use an NSTabView without tabs, because then all your views are at all times in the window (possibly hidden) and the tabview takes care of the resizing.

您的问题的一个很好的解决方案可能是使用没有选项卡的 NSTabView,因为这样您的所有视图始终都在窗口中(可能隐藏)并且 tabview 负责调整大小。

Another solution is to put several views on top of each other and use setHidden:to show only one.

另一种解决方案是将多个视图放在一起,并用于setHidden:仅显示一个视图。