NSStackView和具有固有内容大小的子视图

pfa*_*ade 3 cocoa autolayout nsstackview

我有一个NSStackView以编程方式创建,并向其中添加了一个NSButton。

    NSStackView *stackView = [[NSStackView alloc] initWithFrame:rect];
    stackView.autoresizingMask = NSViewWidthSizable|NSViewHeightSizable;
    stackView.alignment = NSLayoutAttributeBaseline;
(...)
    NSButton *button = [[NSButton alloc] initWithFrame:CGRectMake(0, 0, 40, 50)];
    button.image = item.image;
    button.title = item.name;
    button.bordered = NO;
    button.imagePosition = NSImageAbove;
    button.translatesAutoresizingMaskIntoConstraints = NO;
(...)

    [stackView addView:button inGravity:NSStackViewGravityLeading];
Run Code Online (Sandbox Code Playgroud)

我期望这已经足够,因为按钮具有固有的内容大小(我检查了它是否返回了适当的值)。

检查视图层次结构,我可以看到按钮框是origin =(x = 0,y = 0)size =(width = 40,height = 50),其超级视图(NSStackViewContainer的一个实例)是origin = {x = 0 ,y = 0)size =(width = 0,height = 0),而NSStackView是origin =(x = 0,y = 0)size =(width = 400,height = 50)。

如您所见,NSStackViewContainer的宽度和高度为0 ...

如果我在按钮上添加了宽度和高度限制,则一切正常。为什么按钮的internalContentSize不够?

Tay*_*lor 5

[stackView constraints]可能返回一个空数组-这是不正确的并导致了问题。如果是这样,那么当堆栈视图在窗口中时,没有任何东西触发更新约束或布局的初始传递。

在窗口中添加您自己的约束足以触发它,但是如果不是这样,NSStackView应该能够自身触发(这可能值得一提。)


解决此问题而不增加不必要约束的一种方法是调用:

[window updateConstraintsIfNeeded];
Run Code Online (Sandbox Code Playgroud)

要么

[window layoutIfNeeded];
Run Code Online (Sandbox Code Playgroud)

将StackView添加到窗口后。


更新:在Yosemite,10.10的NSStackView中已修复此问题。