In OSX 10.8, how to limit a subview to the same size as its parent view

I have a default NSWindow created in a new application that has one NSView. Then I create a new NSViewController that has its own XIB and view. In the application delegate, I am doing the obvious

self.mainViewController = [[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil]; [self.window.contentView addSubview:self.mainViewController.view]; self.mainViewController.view.frame = ((NSView*)self.window.contentView).bounds; 

OK, how can I set a limit in a new way so that my subview keeps its size identical to the window, i.e. he controlled. It seems to work automatically. Autoresizessubviews is included for both views.

+8
cocoa constraints nsview macos
source share
6 answers

Basically, you need to limit four things:

  • the leading space of your subtask for its supervisor should be zero
  • the top space of your subquery must be zero for its supervisor
  • the width of your subtask will be equal to the width of the supervisor
  • the height of your subtask will be equal to the width of the supervisor

If a visual constraint does not work for you, you can build these four constraints individually in code. Use the +constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier: constant: method to specify exact relationships between attributes of different views. For example, restriction No. 1 above can be expressed:

 [NSLayoutConstraint constraintWithItem:mySubview attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:mySuperview attribute:NSLayoutAttributeLeading multiplier:1.0f constant:0.0f] 

and # 3 can be:

 [NSLayoutConstraint constraintWithItem:mySubview attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:mySuperview attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0.0f] 

Once you create these four constraints, you can add them to your supervisor as needed.

Note that there are several ways to achieve the same effect as above:

  • You can limit the end space and bottom space instead of width and height
  • You can limit the center of X and the center of Y instead of the top and top spaces

You may also encounter the same limitations in visual presentation as in Peter Hawesy's answer. For example, an equal-width constraint might look like @"[mySubview(==mySuperview)]" with the corresponding view dictionary.

Keep in mind that the Auto Layout Guide provides extensive information on limitations, including how to debug them when something goes wrong.

+7
source share

In the nib editor, drag the size of the subview until it is the same size as its supervisor. Xcode will automatically create an appropriate width limit.

In code, I would try |-0-[mySubview]-0-| (adapted from an example in the documentation of constraint syntax ).

+4
source share

As Peter wrote, you should use a visual format language.

In doing this, however, the order is important: when creating a constraint, all the views it refers to must be part of the same hierarchy of views.

Therefore, given your example, the code should become:

 self.mainViewController = [[MainViewController alloc] initWithNibName:@"MainViewContoller" bundle:nil]; NSView *containerView = self.window.contentView; NSView *contentView = self.mainViewController.view; [contentView setTranslatesAutoresizingMaskIntoConstraints: NO]; [containerView addSubview:contentView]; NSDictionary *viewBindings = NSDictionaryOfVariableBindings(contentView); [containerView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[contentView]|" options:0 metrics:nil views:viewBindings]]; [containerView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[contentView]|" options:0 metrics:nil views:viewBindings]]; 
+2
source share

You can override setContentView :, contentView: and contentRectForFrameRect: so they will deal with a window.frame sized view.

0
source share

If you agree to using a third-party library, you can accomplish this with ReactiveCocoaLayout in one simple line:

 RAC(view,rcl_frame) = parentView.rcl_frameSignal; 
0
source share

I had the same problem and I ended up with this solution that works with SDK 10.10. Just set the autoresizingMask new view to the same as the parent window. Only one line of code and works like a charm ...

 self.masterViewController = [[MasterViewController alloc] initWithNibName:@"MasterViewController" bundle:nil]; [self.window.contentView addSubview:self.masterViewController.view]; self.masterViewController.view.frame = ((NSView *)self.window.contentView).bounds; self.masterViewController.view.autoresizingMask = ((NSView *)self.window.contentView).autoresizingMask; 
-one
source share

All Articles