I need to show multiple views aligned vertically inside NSScrollView
, I started by adding NSTableView
and NSButton
. I aligned them vertica
The problem seems to be that the table view has no intrinsic height. Therefore, it's not "pushing" against the document view's bounds to make the document view larger, so it scrolls.
I notice that if I add a table view to a window in IB and then tell IB to reset the whole window (or the clip view or table view) to suggested constraints, there are no constraints added between the table view and the clip view. Also, the table view still has translatesAutoresizingMaskIntoConstraints
enabled. This is different from some other types of views in scroll views. So, I think that IB knows that table views aren't auto layout-savvy.
I believe that a table view directly in a clip view (as IB sets one up) just uses the old style mechanism for positioning and sizing itself. When a table view computes its size (e.g. a row is added), it probably just calls -setFrameSize:
on itself. The clip view monitors its frame by observing NSViewFrameDidChangeNotification
notification. This doesn't work in your case because auto layout basically ignores/undoes attempts to set the frame.
You may be able to work with this, but it will be dicey. You would leave the table view's translatesAutoresizingMaskIntoConstraints
on, but that imposes limits on what constraints you can set without causing conflicts. Basically, you can't set constraints that impose a position or size on the table view, but you can "hang" other views off of the table view so long as they are free to move or resize so that the table view is free to move and resize.
First, your document view (tempView
) should be a flipped view, because you're going to want to position the table view at its top by setting its frame and then it's going to resize itself by setting its frame size and you want it to grow down.
Init the document view with a frame with non-zero size. The origin doesn't matter.
Init the table view with a frame whose origin is at (0, 0) and with the same size as the document view. Don't forget to leave its translatesAutoresizingMaskIntoConstraints
on.
Do not constrain the top, leading, or trailing edges of the table view to its superview. Don't constrain its width to match the button. The other constraints between the table view and its superview and button are fine, I think. So, kViewVertical
should drop the first |
. You should get rid of kTextViewHorizontal
entirely. kButtonHorizontal
is fine.
Set the table view's autoresizingMask
to NSViewWidthSizable
. Since the table view started with a frame coincident with its superview's bounds, that will keep the table view's left and right edges matching the superview's. There is no vertical component of the autoresizingMask
. Basically, you don't want changes in the height of the superview to try to change the height of the table view. The table view is free to set its own frame height. That will move the button, because it's constrained to the table view's bottom, and that will change the height of the document view, because its bottom is constrained to the button's bottom.
Do not constrain the document view (tempView
) to the clip view on its bottom edge. That just tries to force the document view to be the size of the contentSize
of the scroll view. That is sure to prevent scrolling (by making the scroll view and the window grow to show the entire document view). Rather, the document view will change size as discussed in the previous paragraph and the clip view will notice that and update the scroll view accordingly.
I think that at this point, things will mostly work. I suspect that when the scroll view is large enough to show both the button and the whole table view, they will be pinned to the bottom of the scroll view rather than the top which would be more natural. To fix that, use a subclass of NSClipView
that is flipped.