For a MacOS app, I have a Window, containing an NSView
; into that view, I want to add a subview with a constant size and height.
When loading the subview programmatically by [myView addSubview:mySubview]
, I want the NSView *myView
that is hosting the subview to change in size so it accomodates the subview, and the window to change in size accordingly; so that the edges of the NSView inside that Window keep the same distance to their surroundings in the Window as before. How do I achieve that most efficiently and which properties do I have to specify in IB to make that work? Do I have to adjust the size of myView
and of the Window programmatically by hand or can I achieve this in a more beautiful way?
CodePudding user response:
There are multiple ways to achieve this.
A simple one is to set autoresizingMask
the value(s) you want.
The mask you can see in Interface Builder are represented by predefined numbers (NSAutoresizingMaskOptions
) that you will combine with bit operation
view.autoresizingMask = NSViewMaxXMargin | NSViewMaxYMargin;
which is simmilar to Autoresizing like in this screenshot of IB
The checkmark on Layout Translates Mask Into Constraints has to be made, either in IB or programmatically so they are used as constraints.
view.translatesAutoresizingMaskIntoConstraints = YES;
The relative positioning to its enclosing superview is defined when the view is instanced with
-initWithFrame:
with the given frame or with the values set in IB when it creates an instance and inits the UI element via -initWithCoder:
.
Be aware this does not stop the autolayout mechanism of IB to warn you that your desired coordinates, sizes and constraints are maybe clashing with constraints.
CodePudding user response:
As suggested by @Willeke, I needed to understand and apply Autolayout. To make it work in IB, I set the autoresizingMask
of my subview to stick to all for sides and automatically adjust width and height. Even though it can be done completely in IB, I think programmatically this would be
subview.autoresizingMask = NSViewWidthSizable | NSViewHeightSizeable;
As pointed out by @Ol Sen in his answer, Translates Mask Into Constraints also has to be activated.
To arrange the elements inside that subview that is added programmatically as described in the opening post, I rely on nested stackviews and resize them instead of resizing the parent.
The only problem left is to correctly adjust the frame of the subview to match the parent view before adding it. If this step is left out, the contraints the autoresizing mask of the subview is translated into when adding it will result in the correct resizing behaviour, but wrong margins. The essential code looks like this:
MySubViewController *subViewController = [[MySubViewController alloc] init];
subViewController.view.frame = superView.bounds; // Correct the margins
[superView addSubview:subViewController.view];