如何使用 Cocoa Auto Layout 调整窗口大小的自定义视图? [英] How to make a custom view resize with the window with Cocoa Auto Layout?

查看:30
本文介绍了如何使用 Cocoa Auto Layout 调整窗口大小的自定义视图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个窗口,其中有一个自定义视图,我希望自定义视图随窗口一起调整大小,以便随时完全填满它.如果我写:

NSView *contentView = [self.window contentView];CustomView *customView = [[CustomView alloc] initWithFrame:[contentView bounds]];[contentView addSubview:customView];[内容视图添加约束:[NSLayoutConstraintconstraintWithItem:customView属性:NSLayoutAttributeWidth相关者:NSLayoutRelationEqualtoItem:内容视图属性:NSLayoutAttributeWidth乘数:1常数:0]];[内容视图添加约束:[NSLayoutConstraintconstraintWithItem:customView属性:NSLayoutAttributeHeight相关者:NSLayoutRelationEqualtoItem:内容视图属性:NSLayoutAttributeHeight乘数:1常数:0]];

然后窗口不允许我调整它的大小.
如果我添加:

[customView setTranslatesAutoresizingMaskIntoConstraints:NO];

然后自定义视图不会出现(drawRect: 似乎永远不会被调用).我尝试了不同的方法(包括视觉格式 @"|[customview]|"),但我总是遇到同样的问题.我知道可以使用较旧的自动调整大小系统来完成:

[customView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];

但是我想使用 Cocoa Auto Layout 系统,并且我想将它用于更复杂的情况(比如总是填满窗口的几个自定义视图).

有谁知道出了什么问题,我应该如何使用自动布局系统来获得我想要的结果?

解决方案

使用自动布局,有(至少)三种可能的方法来约束视图,使其占据整个窗口的内容视图,并在适当的时候调整大小.

>

关于超级视图的视觉格式限制

NSView *contentView = [_window contentView];MyView *customView = [[MyView alloc] initWithFrame:[contentView bounds]];[customView setTranslatesAutoresizingMaskIntoConstraints:NO];[contentView addSubview:customView];NSDictionary *views = NSDictionaryOfVariableBindings(customView);[内容视图添加约束:[NSLayoutConstraint constraintWithVisualFormat:@"H:|[customView]|"选项:0指标:无意见:意见]];[内容视图添加约束:[NSLayoutConstraint constraintWithVisualFormat:@"V:|[customView]|"选项:0指标:无意见:意见]];

边缘的编程约束

(这应该相当于上面的可视化格式)

+ (void)addEdgeConstraint:(NSLayoutAttribute)edge superview:(NSView *)superview subview:(NSView *)subview {[superview addConstraint:[NSLayoutConstraint constraintWithItem:subview属性:边相关者:NSLayoutRelationEqualtoItem:超级视图属性:边乘数:1常数:0]];}

NSView *contentView = [_window contentView];MyView *customView = [[MyView alloc] initWithFrame:[contentView bounds]];[customView setTranslatesAutoresizingMaskIntoConstraints:NO];[contentView addSubview:customView];[[self class] addEdgeConstraint:NSLayoutAttributeLeft superview:contentView subview:customView];[[self class] addEdgeConstraint:NSLayoutAttributeRight superview:contentView subview:customView];[[self class] addEdgeConstraint:NSLayoutAttributeTop superview:contentView subview:customView];[[self class] addEdgeConstraint:NSLayoutAttributeBottom superview:contentView subview:customView];

大小的编程约束

NSView *contentView = [_window contentView];MyView *customView = [[MyView alloc] initWithFrame:[contentView bounds]];[customView setTranslatesAutoresizingMaskIntoConstraints:NO];[contentView addSubview:customView];[内容视图添加约束:[NSLayoutConstraintconstraintWithItem:customView属性:NSLayoutAttributeWidth相关者:NSLayoutRelationEqualtoItem:内容视图属性:NSLayoutAttributeWidth乘数:1常数:0]];[内容视图添加约束:[NSLayoutConstraintconstraintWithItem:customView属性:NSLayoutAttributeHeight相关者:NSLayoutRelationEqualtoItem:内容视图属性:NSLayoutAttributeHeight乘数:1常数:0]];

<小时>

第三种方法是问题中列出的方法,如果有进一步的限制,它可能不起作用.例如,没有:

[customView setTranslatesAutoresizingMaskIntoConstraints:NO];

也应用了原始的自动调整大小掩码,这会导致问题中描述的行为:窗口未调整大小.

正如 Regexident 所提到的,您可以使用:

[_window visualConstraints:[contentView 约束]];

调试自动布局.也值得检查控制台输出.

I have a single window with a single custom view in it, and I want the custom view to resize with the window so that it entirely fills it at any time. If I write:

NSView *contentView = [self.window contentView];
CustomView *customView = [[CustomView alloc] initWithFrame:[contentView bounds]];
[contentView addSubview:customView];
[contentView addConstraint:
    [NSLayoutConstraint constraintWithItem:customView
        attribute:NSLayoutAttributeWidth
        relatedBy:NSLayoutRelationEqual
        toItem:contentView
        attribute:NSLayoutAttributeWidth
        multiplier:1
        constant:0]];
[contentView addConstraint:
    [NSLayoutConstraint constraintWithItem:customView
        attribute:NSLayoutAttributeHeight
        relatedBy:NSLayoutRelationEqual
        toItem:contentView
        attribute:NSLayoutAttributeHeight
        multiplier:1
        constant:0]];

Then the window doesn't let me resize it.
If I add:

[customView setTranslatesAutoresizingMaskIntoConstraints:NO];

Then the custom view doesn't appear (drawRect: seems to never be called). I tried different ways (including the visual format @"|[customview]|") but I always run into the same problems. I know it could be done with the older autoresizing system, with:

[customView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];

but I want to use the Cocoa Auto Layout system, and I want to use it for more complicated cases (like several custom views that always fill the window).

Does anyone know what is wrong and how I should use the Auto Layout system to get the result that I want?

解决方案

With Auto Layout, there are (at least) three possible ways to constrain a view so that it occupies the entire window’s content view, resizing when appropriate.

Visual format constraints with regard to superview

NSView *contentView = [_window contentView];
MyView *customView = [[MyView alloc] initWithFrame:[contentView bounds]];
[customView setTranslatesAutoresizingMaskIntoConstraints:NO];

[contentView addSubview:customView];

NSDictionary *views = NSDictionaryOfVariableBindings(customView);

[contentView addConstraints:
    [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[customView]|"
        options:0
        metrics:nil
        views:views]];

[contentView addConstraints:
    [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[customView]|"
    options:0
    metrics:nil
    views:views]];

Programmatic constraints for the edges

(this should be equivalent to the visual format above)

+ (void)addEdgeConstraint:(NSLayoutAttribute)edge superview:(NSView *)superview subview:(NSView *)subview {
    [superview addConstraint:[NSLayoutConstraint constraintWithItem:subview
        attribute:edge
        relatedBy:NSLayoutRelationEqual
        toItem:superview
        attribute:edge
        multiplier:1
        constant:0]];
}

and

NSView *contentView = [_window contentView];
MyView *customView = [[MyView alloc] initWithFrame:[contentView bounds]];
[customView setTranslatesAutoresizingMaskIntoConstraints:NO];

[contentView addSubview:customView];

[[self class] addEdgeConstraint:NSLayoutAttributeLeft superview:contentView subview:customView];
[[self class] addEdgeConstraint:NSLayoutAttributeRight superview:contentView subview:customView];
[[self class] addEdgeConstraint:NSLayoutAttributeTop superview:contentView subview:customView];
[[self class] addEdgeConstraint:NSLayoutAttributeBottom superview:contentView subview:customView];

Programmatic constraint for the size

NSView *contentView = [_window contentView];
MyView *customView = [[MyView alloc] initWithFrame:[contentView bounds]];
[customView setTranslatesAutoresizingMaskIntoConstraints:NO];

[contentView addSubview:customView];

[contentView addConstraint:
    [NSLayoutConstraint constraintWithItem:customView
        attribute:NSLayoutAttributeWidth
        relatedBy:NSLayoutRelationEqual
        toItem:contentView
        attribute:NSLayoutAttributeWidth
        multiplier:1
        constant:0]];
[contentView addConstraint:
    [NSLayoutConstraint constraintWithItem:customView
        attribute:NSLayoutAttributeHeight
        relatedBy:NSLayoutRelationEqual
        toItem:contentView
        attribute:NSLayoutAttributeHeight
        multiplier:1
        constant:0]];


The third approach is the one listed in the question and it may not work if there are further constraints. For example, without:

[customView setTranslatesAutoresizingMaskIntoConstraints:NO];

the original autoresize mask is applied as well, which leads to the behaviour described in the question: the window isn’t resized.

As mentioned by Regexident, you can use:

[_window visualizeConstraints:[contentView constraints]];

to debug Auto Layout. It’s worth checking the console output as well.

这篇关于如何使用 Cocoa Auto Layout 调整窗口大小的自定义视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆