Xcode 如何使用NSLayoutConstraint使子视图占据superview的剩余/总高度

Xcode 如何使用NSLayoutConstraint使子视图占据superview的剩余/总高度,xcode,cocoa,Xcode,Cocoa,我有一个superview,其中添加了两个子视图(子视图1和子视图2) 我希望子视图1的宽度与superview相同,并使用superview拉伸,高度为30px,并与superview顶部对齐。这是我可以使用以下代码得到的: NSDictionary *metrics = @{@"height":[NSNumber numberWithFloat:30.0f]}; NSDictionary *views = NSDictionaryOfVariableBindings(subview1); N

我有一个superview,其中添加了两个子视图(子视图1和子视图2)

我希望子视图1的宽度与superview相同,并使用superview拉伸,高度为30px,并与superview顶部对齐。这是我可以使用以下代码得到的:

NSDictionary *metrics = @{@"height":[NSNumber numberWithFloat:30.0f]};
NSDictionary *views = NSDictionaryOfVariableBindings(subview1);
NSArray *tabContainerConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[subview1(==height)]" options:NSLayoutFormatAlignAllTop metrics:metrics views:views];
[superview addConstraints:tabContainerConstraints];

metrics = nil;
tabContainerConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[subview1]|" options:(NSLayoutFormatAlignAllLeading | NSLayoutFormatAlignAllTrailing) metrics:metrics views:views];
[superview addConstraints:tabContainerConstraints];
然后,我希望子视图2的宽度与superview相同,并使用superview进行拉伸,同时我希望子视图2的顶部与子视图1的底部对齐,然后我希望子视图2填充superview的所有剩余高度(从下到下对齐),并使用superview进行高度拉伸。我尝试使用以下代码执行此操作:

NSDictionary *metrics = nil;
NSDictionary *views = NSDictionaryOfVariableBindings(subview2);
NSArray *tabContainerConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[subview2]|" options:(NSLayoutFormatAlignAllLeading | NSLayoutFormatAlignAllTrailing) metrics:metrics views:views];
[superview addConstraints:tabContainerConstraints];

views = NSDictionaryOfVariableBindings(subview1, subview2);
tabContainerConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[subview1][subview2]-0-|" options:0 metrics:metrics views:views];
[superview addConstraints:tabContainerConstraints];
但是奇怪的事情发生了。。。子视图始终与其顶部对子视图1的底部对齐,并且具有superview的全宽,因此这很好。但是身高很奇怪。。。当第一次绘制/显示的子视图2的高度非常有限时,似乎在20-30像素之间,但我可以通过切换到另一个选项卡/视图并返回来强制重画,然后以完全/正确的高度绘制。我的子视图2是一个NSTextView,当我键入文本时,奇怪的事情发生了,我的子视图2突然没有占据所有高度,并且不再与superview的底部对齐

我希望我的解释是好的,如果没有请问任何问题。有没有办法解决这个问题?我以为|-0-[view]-0-|会奏效

谢谢你

Søren

从您的问题中不清楚您是否正在运行所有代码,或者第一个代码段仅用于一个视图,第二个代码段用于两个视图

您应该将两个VFL字符串组合成一个字符串,并且不需要提供一些布局选项。如果VFL字符串中只有一个视图,则布局选项没有意义

我建议使用以下代码来创建约束:

NSDictionary *metrics = @{@"height":[NSNumber numberWithFloat:30.0f]};
NSDictionary *views = NSDictionaryOfVariableBindings(subview1,subview2);

// Horizontal layout for subview 1
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[subview1]|" options:0 metrics:metrics views:views]];

// Vertical layout - the options here mean that subview2 will be the same width as subview1
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[subview1(==height)][subview2]|" options:NSLayoutFormatAlignAllLeft | NSLayoutFormatAlignAllRight metrics:metrics views:views]];

如果文本视图中有或没有内容时表现不同,则文本视图的固有大小可能会有一些问题。或者,superview本身可能正在更改其大小-superview上的约束是什么?您需要设置一些边框/背景颜色,或者使用自省工具来确定哪些帧会变得有趣

您的问题不清楚您是在运行所有这些代码,还是第一个代码段仅用于一个视图,第二个代码段用于两个视图

您应该将两个VFL字符串组合成一个字符串,并且不需要提供一些布局选项。如果VFL字符串中只有一个视图,则布局选项没有意义

我建议使用以下代码来创建约束:

NSDictionary *metrics = @{@"height":[NSNumber numberWithFloat:30.0f]};
NSDictionary *views = NSDictionaryOfVariableBindings(subview1,subview2);

// Horizontal layout for subview 1
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[subview1]|" options:0 metrics:metrics views:views]];

// Vertical layout - the options here mean that subview2 will be the same width as subview1
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[subview1(==height)][subview2]|" options:NSLayoutFormatAlignAllLeft | NSLayoutFormatAlignAllRight metrics:metrics views:views]];

如果文本视图中有或没有内容时表现不同,则文本视图的固有大小可能会有一些问题。或者,superview本身可能正在更改其大小-superview上的约束是什么?您需要设置一些边框/背景颜色,或者使用自省工具来确定哪些帧会变得有趣

你在控制台里看到什么了吗?在我看来,您正在使用上面的代码创建冲突约束。调试中没有显示任何内容console@jrturton你有什么建议我可以试试解决我的问题吗?你在控制台里看到什么了吗?在我看来,您正在使用上面的代码创建冲突约束。调试中没有显示任何内容console@jrturton您有什么建议我可以在这里尝试解决我的问题吗?是的,我忘了添加一些信息:subview2被动态添加到superview(并被另一个视图删除和替换),这就是为什么我单独/首先向子视图1添加约束。这会改变情况吗?我不能同时将约束添加到子视图1和子视图2,因为它们不能同时添加到superview。在这种情况下,您可以在superview上的自定义
updateConstraints
方法中处理。在该方法中,删除所有约束,然后创建当前子视图所需的任何新约束。更改子视图时,请致电
setNeedsUpdateConstraints:
。不,谢谢,我没有运行电子邮件技术支持服务!我不是OSX爱好者,但问题似乎出在NSTextView上——如果用一个只绘制平面颜色的普通NSView替换它,你就没事了。我认为您不应该直接使用NSTextView,而是应该先将其添加到NSScrollView,如这里和这里所述,希望这会有所帮助!对,我太专注于布局了。谢谢:)是的,我忘了添加一些信息:subview2被动态添加到superview(并被另一个视图删除和替换),这就是为什么我单独/首先向subview1添加约束。这会改变情况吗?我不能同时将约束添加到子视图1和子视图2,因为它们不能同时添加到superview。在这种情况下,您可以在superview上的自定义
updateConstraints
方法中处理。在该方法中,删除所有约束,然后创建当前子视图所需的任何新约束。更改子视图时,请致电
setNeedsUpdateConstraints:
。不,谢谢,我没有运行电子邮件技术支持服务!我不是OSX爱好者,但问题似乎出在NSTextView上——如果用一个只绘制平面颜色的普通NSView替换它,你就没事了。我认为您不应该直接使用NSTextView,而是应该先将其添加到NSScrollView,如这里和这里所述,希望这会有所帮助!对,我太专注于布局了。谢谢:)