【问题标题】:In OSX 10.8 how do I constrain a subview to be the same size as its parent view在 OSX 10.8 中,如何将子视图限制为与其父视图相同的大小
【发布时间】:2012-11-14 03:55:33
【问题描述】:

我在具有单个 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 均处于开启状态。

【问题讨论】:

  • 您打算在 IB 中还是在代码中执行此操作?
  • 我想我会通过将 UIWindow 和视图保留在同一个 xib 文件中来完全避免这个问题。另外,我需要使用 NSWindowController 而不是 NSViewController(大脑中的 iOS 太多)

标签: macos cocoa constraints nsview


【解决方案1】:

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

  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]

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

注意,有多种方式可以达到与上面相同的效果:

  • 您可以限制 尾随空格底部空格 而不是宽度和高度
  • 您可以限制 center Xcenter Y 而不是前导空格和顶部空格

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

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

【讨论】:

  • 我已经通过将所有内容保存在一个 xib 文件中解决了这个问题,但我喜欢这个答案。在我有时间自己尝试之前,我无法标记它。
【解决方案2】:

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

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

【讨论】:

  • 我知道我可以做到这一点,但是 subivew 位于不同的 XIB 中。我尝试了视觉约束,但它所做的只是将父母限制为不小于孩子。认为它一定是错误的约束语法(到目前为止,这东西很混乱)
  • @ahwulf:约束必须能够引用两个对象,因此如果对象位于不同的 nib 中,则不能在 nib 中创建约束——因为您将在哪个 nib 中创建它?
  • 是的,它需要在代码中,但目前还不清楚它应该是什么样子。
【解决方案3】:

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

但是,这样做时,顺序很重要:创建约束时,它引用的所有视图都必须是同一视图层次结构的一部分。

因此,鉴于您的示例,代码必须变为:

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • NSWindow 的重写方法如何帮助将视图约束为始终与其父视图相同的大小?
    【解决方案5】:

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

    RAC(view,rcl_frame) = parentView.rcl_frameSignal;
    

    【讨论】:

      【解决方案6】:

      我遇到了同样的问题,我最终得到了这个与 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;
      

      【讨论】:

      • 不过,这不是一个约束(即自动布局)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-14
      • 1970-01-01
      • 2014-11-02
      • 2017-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多