在OSX 10.8中,如何将子视图约束为与其父视图相同的大小

时间:2012-11-14 03:55:33

标签: macos cocoa constraints nsview

我在一个具有单个NSView的新应用程序中创建了默认的NSWindow。然后我创建一个新的NSViewController,它有自己的XIB和视图。在app委托中,我做了明显的

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

好的,我如何以新的方式设置约束,让我的子视图保持其大小与Window相同,即它是superview。它似乎不会自动运行。两个视图的Autoresizessubviews都为ON。

6 个答案:

答案 0 :(得分:8)

基本上,你需要约束四件事:

  1. 您的子视图的领先空间到其超级视图为零
  2. 您的超级视图的子视图的顶部空间为零
  3. 子视图的宽度等于其超级视图的宽度
  4. 您的子视图的高度等于其超级视图的宽度
  5. 如果视觉约束不适合您,您可以在代码中单独构建这四个约束。使用方法+constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier: constant:指定不同视图属性之间的确切关系。例如,上面的约束#1可以表示为:

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

    和#3可能是:

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

    一旦你构建了这四个约束,就可以根据需要将它们添加到你的超级视图中。

    请注意,有多种方法可以达到与上述相同的效果:

    • 您可能会限制尾随空格底部空间而不是宽度和高度
    • 您可能会限制中心X 中心Y 而不是前导和顶部空格

    您也可能在视觉表现中提出相同的约束,如Peter Hosey的回答。例如,等宽约束可能看起来像@"[mySubview(==mySuperview)]",带有相应的视图字典。

    请记住Auto Layout Guide是关于约束的大量信息,包括在出现问题时如何调试它们。

答案 1 :(得分:4)

在nib编辑器中,拖动子视图的大小,直到它与superview的大小相同。 Xcode将自动创建适当的宽度约束。

在代码中,我会尝试|-0-[mySubview]-0-|(改编自the constraint syntax documentation中的示例)。

答案 2 :(得分:2)

就像彼得写的那样,你应该使用视觉格式语言。

但是,执行此操作时,顺序很重要:创建约束时,它引用的所有视图都必须属于同一视图层次结构。

所以给出你的例子,代码必须成为:

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]];

答案 3 :(得分:0)

你可以覆盖setContentView:,contentView:和contentRectForFrameRect:所以他们将处理window.frame大小的视图。

答案 4 :(得分:0)

如果您对使用第三方库感到满意,可以使用ReactiveCocoaLayout在一个简单的行中完成此操作:

RAC(view,rcl_frame) = parentView.rcl_frameSignal;

答案 5 :(得分:-1)

我遇到了同样的问题,我最终得到了这个与SDK 10.10一起使用的解决方案。只需将新视图的autoresizingMask设置为与父窗口相同即可。只有一行代码,它就像一个魅力......

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;