使用自动布局将NSView调整为其子视图

时间:2014-05-18 15:50:46

标签: objective-c cocoa autolayout nsview nsscrollview

在Interface Builder中,我添加了一个NSScrollView NSImageView,一些标签,一个水平分隔符和一个NSViewNSScrollView如下所示: The NSScrollView

每个元素都有左上角的约束,分隔符和自定义视图都有一个右边的约束。

有时我需要更改自定义视图的内容。我使用以下代码执行此操作(options是自定义视图,view是我要显示的视图):

[view setTranslatesAutoresizingMaskIntoConstraints:NO];
options.subviews = [NSArray arrayWithObject:view];

// Fix the constraints.
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(view);
[options addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view]|" options:0 metrics:nil views:viewsDictionary]];
[options addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:0 metrics:nil views:viewsDictionary]];

这在某种程度上起作用:在视图中显示正确的内容,并根据约束更改内容的宽度。但是,options视图的高度不会更改,因此不会显示view视图的某些内容。我试图通过手动设置框架来改变这一点,但这不起作用。另外,我尝试了以下设置约束:

[options addConstraint:[NSLayoutConstraint constraintWithItem:options attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeHeight multiplier:1 constant:0]];

但没有任何作用。有谁知道我怎么解决这个问题?

我注意到的第二个问题是,即使NSScrollView的内容大于NSScrollView本身,滚动也不起作用。没有显示滚动条。我该如何解决这个问题?

我仍然无法理解约束中存在的这些更难的问题......

1 个答案:

答案 0 :(得分:0)

我设法解决了我的问题。事实证明我确实有两个问题:

  1. 我没有在NSScrollView及其子代上设置正确的约束;
  2. 我更改了自定义视图的内容,但未更改其高度。
  3. 我对两个问题的解决方法如下。


    NSScrollView约束

    在Interface Builder中添加NSScrollView并在文档视图中放置一些UI元素(剪辑视图的子视图)后,我有了以下界面(窗口的白色部分是NSScrollView,不要查看约束条件现在): Interface

    如果您运行此操作并调整窗口大小,则不会显示滚动条。首先,我们必须在文档视图中添加相对于其超级视图的顶部和前导约束。现在我们需要指定文档视图的大小。这可以通过两种方式完成,具体取决于您的用例:

    1. 为文档视图的宽度和高度添加约束。这样,始终显示相同的滚动条。然而,文档视图不会根据内容更改大小,除非您自动更新这些约束;
    2. 为文档视图的每个子项添加约束,以便可以计算文档视图的宽度和高度。这是我的问题所必需的,这些约束显示在上面的图片中。
    3. 如果你运行它,一切都按预期工作。我们仍然无法更改自定义视图的内容,这是一个不同的问题。


      更改自定义视图

      现在我们只需要更改自定义视图的内容。由于我们在自定义视图上设置了约束,因此也应该更改这些约束。所有这些都是通过以下自解释代码完成的(自定义视图名为content):

      - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
          [content setAutoresizesSubviews:NO];
      }
      
      - (IBAction)button1:(id)sender {
          [self showContent:view1];
      }
      
      - (IBAction)button2:(id)sender {
          [self showContent:view2];
      }
      
      - (void)showContent:(NSView *)c {
          // Remove all constraints.
          [content removeConstraints:content.constraints];
      
          // Add a height constraint.
          NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:content attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:c.frame.size.height];
          [content addConstraint:constraint];
      
          // Add a width constraint.
          NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:content attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:c.frame.size.width];
          [content addConstraint:constraint];
      
          [c setTranslatesAutoresizingMaskIntoConstraints:NO];
      
          // Set the content.
          content.subviews = [NSArray arrayWithObject:c];
      
          // Add constraints from the content view to its child view.
          NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(c);
          [content addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[c]|" options:0 metrics:nil views:viewsDictionary]];
          [content addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[c]|" options:0 metrics:nil views:viewsDictionary]];
      }
      

      我希望这个答案可以帮助别人找到NSScrollView和autolayout的奇怪行为。