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

问题描述:

我正在玩可可的Autolayout,有些事情对我来说并不明确。如何使用Cocoa Autolayout根据优先级调整两个子视图?

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

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

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

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

当视图2达到其最小尺寸我想视图1被调整到它的最小尺寸。

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

我该怎么做?

布局似乎有点不明确。什么时候view2开始缩小而不是匹配view1的大小?我认为在view1达到最低限度之前视图应该是相同的大小。此时,view2会调整大小,直到达到最小值,然后调整view1大小,直到达到最小值。

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

  1. 厂景和视图2> =最小
  2. 厂景> = view1SoftMinimum
  3. 厂景==视图2

Contraint 1必须在窗口调整大小优先上方。我们可以使它成为必需的(这是默认的)。

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

Contraint 3必须低于contraint 2,所以我们将其479

我们可以表达所有这些约束上的一个视觉格式字符串,您可以添加

|[view1(>=view1Minimum,>[email protected],[email protected])][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,>[email protected],[email protected])]-[view2(>=view2Minimum)]|" options:0 metrics:metrics views:viewsDictionary]];