在iOS中使用自动布局,我该如何指定一个视图尽可能地占据空间?

17

我正在iOS中使用自动布局尝试构建具有流体宽度的布局。我目前正在使用的约束的可视格式为:

[self.scrollViewContainer addConstraints:[NSLayoutConstraint 
     constraintsWithVisualFormat:@"H:|-(>=32)-[viewToAdd(<=576)]-(>=32)-|" 
                         options:0 
                         metrics:nil  
                           views:NSDictionaryOfVariableBindings(viewToAdd)
]];

换句话说:我希望两侧至少有32像素的间距,并且我希望viewToAdd的最大宽度为576像素。这个方案很好,但是我想让viewToAdd充分利用所有可用空间,同时仍满足所有约束条件。目前,viewToAdd的宽度只能达到其内在内容大小,而间距会根据需要增加。

有没有一种方法可以指定viewToAdd尽可能大?

2个回答

35

为了让视图填充剩余的可用空间,您需要在视图上指定额外的约束条件。目前,您只设置了视图的最小值和最大值,但没有设置任何具体的约束条件来提供自动布局的更完整解决方案。除了宽度的上限之外,您还需要给它 1.一个起点来解决视图的宽度,可以通过显式地给它一个低优先级的宽度或者2.给两侧的间距一些更严格的约束。

根据您所描述的情况,您需要将您的视图约束到超级视图的两侧,以便让系统解决宽度。由于您希望视图的大小基于其容器的大小进行调整,因此您需要修改间距约束(以上述选项2为例)。在上面的示例中,您仅指定了最小间距,这将导致自动布局引擎找到以下任何一种约束解决方案都是有效的约束解决方案,适用于400pt的超级视图:

|-32pt-[20pt]-------348pt-| <-- autolayout will probably choose this one
|-100pt----[20pt]---280pt-|
|-50pt--[20pt-]-----330pt-|

这可能不是您想要的。此外,视图的宽度可以在0-576pt之间任意设置,这也可能不是您想要的。由于自动布局不知道您想要什么,因此它只是使用视图的intrinsicContentSize进行具体大小约束。由于您选择了32pt作为间距,第一步应该是给间距约束一些更实质性的指示,即告诉系统,除非视图的宽度> 576pts,否则间距应该是在视图和父视图的边缘之间为32pts。在VFL字符串中,您可以像这样执行:

"H:|-(>=32,==32@900)-[viewToAdd(<=576)]-(>=32,==32@900)-|"

这段话的意思是:“viewToAdd 应该有一个最大宽度为 576pts,并且与其 superview 之间的内边距应为 32pts。当 superview 的大小超出 viewToAdd 的最大宽度加上初始内边距 64pts 时,两侧的内边距应该增长以继续解决约束集合。”

这将导致以下约束对于 400pt 的 superview 是正确的:

|-32pt--[336pt]--32pt-|

如果你希望viewToAdd在视图增长超过最大值时仍保持居中,那么你需要在[NSLayoutConstraint -constraintsWithVisualFormat:]方法的options参数中传递选项NSLayoutFormatAlignAllCenterX。如果你没有在填充上设置>=32的约束,或者没有在填充的==32约束上设置低于1000(“必须”约束优先级级别)的优先级,则你的父视图将无法增长超过640pts。


1
似乎我之前说的只需将选项 NSLayoutFormatAlignAllCenterX 传递给可视化格式,就可以使视图在父视图中居中的说法是不正确的。这些选项仅适用于您在可视化格式字符串中明确引用的视图。因此,看起来您需要另一个明确的约束,将视图的中心约束到父视图的中心。 - larsacus
1
谢谢 - 我已经在单独的约束中将其居中了:[self.scrollViewContainer addConstraint:[NSLayoutConstraint constraintWithItem:viewToAdd attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.scrollViewContainer attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]]; - simon

1

不确定是否完全回答了问题,但对于使用Storyboard的人:我发现您可以添加宽度约束以及与父视图左侧和右侧的距离的约束。如果您将宽度约束更改为“<=”,并将距离约束(前导和尾随)的优先级设置为750,则视图将最大化到最大宽度,如果视图太小则会遵守距离约束。

The constraints in place


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接