Search code examples
objective-cxcodecocoaautolayoutnsstackview

Autolayout: NSStackView won't resize parent view when height dynamically changed


Similar question: How to resize a parent view based on the size of subviews layouted with Autolayout

I got an NSStackView which loads DisclosureViewControllers (NSViewController subclasses) just like in the Apple Example InfoBarStackView.

Apple's example InfoBarStackView

Those can expand and retract views of arbitrary height. I would like the parent view containing the NSStackView to resize its height according to the contents of the NSStackView. In the Apple example that works.

However, unfortunately, Apple is resizing a NSWindow and I am using a CCNStatusItem (CCNStatusItem Github), a view that attaches to the status item in the Apple menu bar. That window resizes to the contents of the NSStackView when it loads, but doesn't resize when the contents change.

CCNStatusItem window after loading the view

When I expand a section, the content overflows and gets clipped on the bottom edge of the view.

CCNStatusItem window with extended DisclosureViewController

I went through all the constraints and tried to reproduce it exactly, but couldn't get it to work. In the Apple example, they are adding everything programmatically, whereas I added a NSStackView in Interface Builder.

Here are the constraints of the NSStackView: enter image description here

My question would be: What constraints do I have in the Interface Builder (with what priorities), so that the parent view (the window) resizes with the contents of the stack view dynamically? Do I have to call some method of the view to make it work?

Please let me know if I missed to provide some necessary information.

UPDATE

The accepted answer was the right way to do it. Here's the result. My forked version of CCNStatusItem can be found at https://github.com/julianvogels/CCNStatusItem.git

Sliding now works!


Solution

  • The problem is that CCNStatusItem is not auto-layout-compatible. It sets the content view of its window to an instance of one of its own view classes (CCNStatusItemWindowBackgroundView). Your view is a subview of that view.

    When it creates and adds its view, it does not turn off translatesAutoresizingMaskIntoConstraints or use constraints to position it relative to its superview. That basically means it can't be forced to a different size by constraints.

    Likewise, when it adds your view to the background view, it does not turn off translatesAutoresizingMaskIntoConstraints on your view nor does it set up constraints to relate your view to the background view.

    Since you've got the source, you can make those changes.