如何使用 Cocoa Autolayout 根据优先级调整两个子视图的大小?

Posted

技术标签:

【中文标题】如何使用 Cocoa Autolayout 根据优先级调整两个子视图的大小?【英文标题】:How to resize two subviews based on priorities using Cocoa Autolayout? 【发布时间】:2012-06-28 12:27:10 【问题描述】:

我在 Cocoa 中使用 Autolayout,有些事情我不清楚。

我在一个窗口上有 2 个视图。每个视图的宽度是父窗口宽度的1/2。

|           |           |
|           |           |
|   View1   |   View2   |
|           |           |
|           |           |

如果我调整窗口大小,我希望 View2 先调整大小。

|           |     |
|           |     |
|   View1   |View2|
|           |     |
|           |     |

当 View2 达到其最小尺寸时,我希望 View1 调整为最小尺寸。

|     |     |
|     |     |
|View1|View2|
|     |     |
|     |     |

我该怎么做?

【问题讨论】:

【参考方案1】:

布局似乎有点不确定。 view2 什么时候开始缩小而不是匹配 view1 的大小?我假设视图应该是相同的大小,直到 view1 达到软最小值。此时,view2 会调整大小直到达到最小值,然后 view1 会调整大小直到达到最小值。

我们可以通过向约束添加优先级来实现这种行为。我们按照重要性排序:

    view1 和 view2 >= 最小值 view1 >= view1SoftMinimum view1 == view2

约束 1 必须高于窗口大小调整优先级。我们可以将其设为必需(这是默认设置)。

约束 2 必须高于约束 3,但低于 NSLayoutPriorityDragThatCannotResizeWindow。我们将使其达到 480。

约束 3 必须低于约束 2,因此我们将其设为 479。

我们可以用一个可视化的格式字符串来表达所有这些约束,你可以添加它

|[view1(>=view1Minimum,>=view1SoftMinimum@480,==view2@479)][view2(>=view2Minimum)]|

这是我测试的代码:

NSView *view1 = [[NSTextView alloc] initWithFrame:NSZeroRect];
NSView *view2 = [[NSTextView alloc] initWithFrame:NSZeroRect];

[view1 setTranslatesAutoresizingMaskIntoConstraints:NO];
[view2 setTranslatesAutoresizingMaskIntoConstraints:NO];

NSView *contentView = [self.window contentView];

[contentView addSubview:view1];
[contentView addSubview:view2];

NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(view1, view2);

[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view1]|" options:NSLayoutConstraintOrientationVertical metrics:NULL views:viewsDictionary]];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view2]|" options:NSLayoutConstraintOrientationVertical metrics:NULL views:viewsDictionary]];


NSDictionary *metrics = [NSDictionary dictionaryWithObjectsAndKeys:
                         [NSNumber numberWithFloat:300], @"view1SoftMinimum",
                         [NSNumber numberWithFloat:150], @"view1Minimum",
                         [NSNumber numberWithFloat:150], @"view2Minimum", nil];

[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[view1(>=view1Minimum,>=view1SoftMinimum@480,==view2@479)]-[view2(>=view2Minimum)]|" options:0 metrics:metrics views:viewsDictionary]];

【讨论】:

以上是关于如何使用 Cocoa Autolayout 根据优先级调整两个子视图的大小?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 AutoLayout 根据父高度调整子视图高度而不添加/删除约束

使用 Autolayout 根据宽度的比率设置 UIImage 高度

如何在 Xcode 6.3 中使用 AutoLayout 创建 ScrollView

XCODE/Swift Autolayout ScrollView with dynamic label, textview etc. 如何根据 textview 设置滚动视图高度

如何在后端动态定义 Autolayout

Cocoa:根据来自 App Delegate 的输入加载不同的视图控制器