9

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

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

好的,我如何以新的方式设置约束以使我的子视图保持其大小与窗口相同,即它的超级视图。它似乎不会自动工作。两个视图的 Autoresizessubviews 都打开。

4

6 回答 6

8

基本上,您需要限制四件事:

  1. 您的子视图到其父视图的前导空间为零
  2. 您的子视图与其父视图的顶部空间为零
  3. 子视图的宽度等于其父视图的宽度
  4. 子视图的高度等于其父视图的宽度

如果视觉约束不适合您,您可以在代码中单独构建这四个约束。使用该方法+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包含大量有关约束的信息,包括在出现问题时如何调试它们。

于 2012-12-03T19:41:25.257 回答
4

在 nib 编辑器中,拖动子视图的大小,直到它与其父视图的大小相同。Xcode 会自动创建一个合适的宽度约束。

在代码中,我会尝试|-0-[mySubview]-0-|(改编自约束语法文档中的示例)。

于 2012-11-14T18:34:43.643 回答
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]];
于 2012-12-03T19:59:33.197 回答
0

如果您可以使用 3rd 方库,您可以使用ReactiveCocoaLayout在一行中完成此操作:

RAC(view,rcl_frame) = parentView.rcl_frameSignal;
于 2013-09-15T12:43:06.363 回答
0

您可以覆盖 setContentView:、contentView: 和 contentRectForFrameRect:,以便它们处理 window.frame 大小的视图。

于 2012-12-05T19:06:49.403 回答
-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;
于 2014-11-02T20:26:01.173 回答