如何使自定义视图调整与Cocoa自动布局的窗口?
我有一个窗口,其中有一个自定义视图,我想要自定义视图调整窗口大小,以便它随时完全填充。
如果我写:
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];
然后自定义视图不出现( drawRect:
似乎永远不会被调用)。
我尝试了不同的方式(包括视觉格式 @| [customview] |
),但我总是遇到相同的问题。我知道它可以用较旧的自动调整系统,与:
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];
但我想使用Cocoa Auto Layout系统,我想将其用于更复杂的情况(像几个自定义视图总是填充窗口)。
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.
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]];
}
和
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.
如Regexident所述,您可以使用:
As mentioned by Regexident, you can use:
[_window visualizeConstraints:[contentView constraints]];
调试自动布局。这也值得检查控制台输出。
to debug Auto Layout. It’s worth checking the console output as well.