Question

I have an NSStackView created programatically to which I add a single 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];

I was expecting this to be sufficient since the button has an intrinsic content size (I checked that it was returning an apropriate value).

Inspecting the view hierarchy I can see that the buttons frame is origin=(x=0, y=0) size=(width=40, height=50), its superview (an instance of NSStackViewContainer) is origin=(x=0, y=0) size=(width=0, height=0) and the NSStackView is origin=(x=0, y=0) size=(width=400, height=50).

As you can see the NSStackViewContainer has 0 width and height...

If I add a width & height constraints to the button everything works fine. Why isn't the button intrinsicContentSize enough?

Was it helpful?

Solution

[stackView constraints] is probably returning an empty array -- which is incorrect and causing the problem. If that's the case, then nothing is triggering an initial pass of updating constraints or layout when the stack view is in the window.

Adding your own constraints in the window would be enough to trigger it, but NSStackView should be able to trigger it itself if it wasn't otherwise (this is probably worth filing a radar over).


One way to work around this, without adding unneeded constraints, is to call:

[window updateConstraintsIfNeeded];

or

[window layoutIfNeeded];

after the StackView has been added to the window.


Update: This is fixed in NSStackView in Yosemite, 10.10.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top