objective-c - 使用自动布局将 NSView 的大小调整为其 subview

标签 objective-c cocoa autolayout nsview nsscrollview

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

每个元素都有来自左上角的约束,分隔符和自定义 View 也有来自右侧的约束。

有时我需要更改自定义 View 的内容。我使用以下代码执行此操作(options 是自定义 View ,view 是我要显示的 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]];

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

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

但是没有任何效果。有谁知道我该如何解决这个问题?

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

我仍然无法解决这些带有约束的更困难的问题......

最佳答案

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

  1. 我没有对 NSScrollView 及其子项设置正确的约束;
  2. 我更改了自定义 View 的内容,但没有更改其高度。

我对这两个问题的修复如下。

<小时/>

NSScrollView 约束

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

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

  1. 添加文档 View 宽度和高度的约束。这样总是显示相同的滚动条。文档 View 将不会根据内容改变大小,除非您自动更新这些约束;
  2. 为文档 View 的每个 subview 添加约束,以便可以计算文档 View 的宽度和高度。这是我的问题所必需的,这些约束显示在上图中。

如果你运行这个,一切都会按预期进行。不过,我们仍然无法更改自定义 View 的内容,这是另一个问题。

<小时/>

更改自定义 View

现在我们只需要更改自定义 View 的内容即可。由于我们对自定义 View 设置了约束,因此也应该更改这些约束。所有这些都是通过以下不言自明的代码完成的(自定义 View 名为 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 和自动布局的奇怪行为的麻烦。

关于objective-c - 使用自动布局将 NSView 的大小调整为其 subview ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23723843/

相关文章:

cocoa - 在 2 个 cocoa 应用程序之间共享配置设置

cocoa - 为什么当我输入字符时,我的 NSTextField 的内在内容大小没有改变?

ios - UIView 宽度和高度不适应约束

ios - UIScrollView + 居中 View + 不明确的可滚动内容大小 + 许多 iPhone 大小

iphone - 禁用 iPhone 屏幕某些区域的触摸事件

ios - 在类实例变量之前声明时出现 NS_ENUM 错误

ios - 在导航栏中使用弹出窗口时后退按钮仍然启用

objective-c - NSPopUpButton 占位符值?

ios - Removed Entity 再次被 MagicalRecord 中的 findFirstByAttribute 找到

cocoa-touch - NSNumberFormatter : string to Double