我一直在玩NSStackView(在OS X 10.9.4上)并且有点卡住了。基本上,我正在创建页脚视图并向此页脚添加堆栈视图。我想在页脚左侧分组一些项目,并将一些项目分组到右侧。我认为可以根据需要将视图分配给前导和尾随重力。但是,我似乎无法获得预期的效果。
NSView* footerView = [[NSView alloc] initWithFrame:CGRectZero];
footerView.translatesAutoresizingMaskIntoConstraints = NO;
self.footerView = footerView;
NSStackView* stackView = [[NSStackView alloc] init];
stackView.translatesAutoresizingMaskIntoConstraints = NO;
self.stackView = stackView;
[self.footerView addSubview:stackView];
NSTextField* firstTextField = [[NSTextField alloc] init];
firstTextField.translatesAutoresizingMaskIntoConstraints = NO;
firstTextField.bezeled = NO;
firstTextField.editable = NO;
firstTextField.stringValue = @"One";
self.firstTextField = firstTextField;
[self.stackView addView:firstTextField inGravity:NSStackViewGravityLeading];
NSTextField* secondTextField = [[NSTextField alloc] init];
secondTextField.translatesAutoresizingMaskIntoConstraints = NO;
secondTextField.bezeled = NO;
secondTextField.editable = NO;
secondTextField.stringValue = @"Two";
self.secondTextField = secondTextField;
[self.stackView addView:secondTextField
inGravity:NSStackViewGravityLeading];
NSTextField* thirdTextField = [[NSTextField alloc] init];
thirdTextField.translatesAutoresizingMaskIntoConstraints = NO;
thirdTextField.bezeled = NO;
thirdTextField.editable = NO;
thirdTextField.stringValue = @"Three";
self.thirdTextField = thirdTextField;
[self.stackView addView:thirdTextField inGravity:NSStackViewGravityLeading];
NSTextField* fourthTextField = [[NSTextField alloc] init];
fourthTextField.translatesAutoresizingMaskIntoConstraints = NO;
fourthTextField.bezeled = NO;
fourthTextField.editable = NO;
fourthTextField.stringValue = @"Four";
self.fourthTextFeild = fourthTextField;
[self.stackView addView:fourthTextField
inGravity:NSStackViewGravityTrailing];
NSTextField* fifthTextField = [[NSTextField alloc] init];
fifthTextField.translatesAutoresizingMaskIntoConstraints = NO;
fifthTextField.bezeled = NO;
fifthTextField.editable = NO;
fifthTextField.stringValue = @"Five";
self.fifthTextField = fifthTextField;
[self.stackView addView:fifthTextField
inGravity:NSStackViewGravityTrailing];
[self.window.contentView addSubview:footerView];
NSDictionary* views = @{
@"footerView" : self.footerView,
@"stackView" : self.stackView
};
[self.window.contentView
addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:[footerView(==30)]|"
options:0
metrics:nil
views:views]];
[self.window.contentView
addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|[footerView]|"
options:0
metrics:nil
views:views]];
[self.footerView
addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-[stackView]-|"
options:0
metrics:nil
views:views]];
[self.footerView
addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|[stackView]|"
options:0
metrics:nil
views:views]];
如果我只添加前三个textFields,那么它们都会在前导区域中正确组合在一起。
但是,当我添加尾随区域视图时,前导区域中的视图会跳转到尾随区域
从NSStackView的文档中获取spacer属性,我看到了
组合起来,这些约束导致以下典型 堆栈视图行为:在hasEqualSpacing属性为的堆栈视图中 设置为NO(默认值),其拥抱优先级保留为 NSLayoutPriorityDefaultLow(默认值),重力区域内的视图 彼此保持固定的距离(等于。的值) 间距属性),重力区域之间的距离增长 随着堆栈视图的增长而收缩,并沿着布局方向收缩 轴。
但是,这似乎并没有发生。重力区域(前导)内的视图之间的间隔不是恒定的,并且不是增加/缩小重力区域之间的距离,而是将其设置为间隔距离。
我想要的是一,二,三出现在页脚左侧(默认距离间隔)和四,五出现在页脚右侧。我可以尝试通过使用两个不同的堆栈视图(一个用于前导区域而另一个用于尾随区域)来实现此目的,但是,我认为这应该可以使用单个堆栈视图和重力区域。希望得到一些指导。感谢
答案 0 :(得分:2)
spacing
NSStackView
属性的文档显示,重叠区间距设置为spacing
值(默认为8个点),堆栈视图为&#39}。配置了该方向的拥抱优先级(默认为NSLayoutPriorityDefaultLow
)。
如果文本字段的内容拥抱优先级低于该值,则自动布局系统将倾向于拉伸其中一个而不是重力区间距。这就是为什么其中一个文本字段被拉伸,如问题所示。 (如果文本字段具有相同的内容拥抱优先级,哪个文本字段被拉伸是任意的,并且可以随时更改。)
如果文本字段的内容拥抱优先级等于堆栈视图的拥抱优先级,那么它将被拉伸的任意内容。它可以是文本字段之一,也可以是重力间距。
您希望让文字字段拥有更高的内容拥抱优先级,正如您在答案中指出的那样。它不需要NSLayoutPriorityDragThatCanResizeWindow
。它可以高于堆栈视图的拥抱优先级。
当你在答案中报告时,这与被限制缩小的窗口无关。
如果您希望堆栈视图允许自身缩小比其子视图指示的大小以及它们之间的间距缩小,则有两个选项。首先,您可以使用NSLayoutPriorityWindowSizeStayPut
将其限幅电阻优先级设置为低于-setClippingResistancePriority:forOrientation:
的值。这将导致堆栈视图允许剪切或分离视图。发生了哪些事情取决于视图的可见性优先级,由setVisibilityPriority:forView:
设置。默认情况下,所有视图的可见性优先级均为NSStackViewVisibilityPriorityMustHold
,这意味着它们不会分离,但会被剪切。
因此,如果您希望分离视图,则应更改其可见性优先级。您应该优先排序,以指明您希望首先分离哪些视图(较低的可见性优先级)相对于其他视图(较高)。
另一种方法是将子视图的压缩阻力优先级设置为低于NSLayoutPriorityWindowSizeStayPut
。这意味着自动布局系统将压缩文本字段,通常用省略号截断它们(" ...")。您可能希望命令文本字段的压缩阻力优先级来确定它们压缩的顺序,否则它将是任意的(甚至可能随时改变)。您可能还希望在文本字段上设置最小宽度约束,因为在某些时候看起来很糟糕,文本字段可见但没有空间显示任何有意义的内容。
您可以通过使文本字段的压缩阻力低于堆栈视图的剪切阻力来组合这两种方法。文本字段的最小宽度约束可能很高甚至是必需的;在任何情况下,都高于堆栈视图的削波电阻。因此,当窗口和堆栈视图缩小时,文本字段将压缩直到达到其最小宽度,然后下一个将压缩,等等。当所有文本字段都处于其最小宽度时,堆栈视图将剪切或分离他们(在能见度优先顺序中),直到他们再次适合。
答案 1 :(得分:0)
我似乎通过将每个文本字段的内容拥抱优先级设置为NSLayoutPriorityDragThatCanResizeWindow来修复它(以某种方式说)。
[firstTextField
setContentHuggingPriority:NSLayoutPriorityDragThatCanResizeWindow
forOrientation:NSLayoutConstraintOrientationHorizontal];
但是,现在这会将窗口框架限制为最小尺寸(允许显示所有文本字段的窗口框架)。它不允许剪切或删除文本字段。