在 iOS 上使用自动布局如何指定视图应占用尽可能多的空间?

Posted

技术标签:

【中文标题】在 iOS 上使用自动布局如何指定视图应占用尽可能多的空间?【英文标题】:Using autolayout on iOS how can I specify that a view should take up as much space as possible? 【发布时间】:2012-10-30 04:24:43 【问题描述】:

我在 ios 中使用自动布局来尝试构建具有可变宽度的布局。我目前使用的约束的视觉格式是:

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

也就是说:我希望两边的最小间距为 32px,我希望 viewToAdd 的最大宽度为 576px。除了我希望 viewToAdd 在满足所有约束的同时用尽所有可用空间之外,这很好用。目前,我得到的 viewToAdd 的宽度仅与其内在内容大小一样宽,并且间距会根据需要增加。

有没有办法指定viewToAdd 应该尽可能大?

【问题讨论】:

【参考方案1】:

您将不得不在视图上指定额外的约束,以使其调整视图的大小以填充剩余的可用空间。目前,您正在设置视图的最小值和最大值,但没有设置任何具体的约束来为自动布局提供更完整的解决方案。除了宽度的上限之外,您还需要给它 1. 一个起点来解决视图的宽度,方法是明确地给它一个较低优先级的宽度,或者 2. 给两边的间距多一些刚性约束。

根据您所描述的,您需要约束您的视图,使其与任一侧的超级视图有更多实质性的绑定,以便让系统解决宽度问题。由于您希望根据容器的大小来设置视图大小,因此您需要修改间距约束(上面的选项 2)。在上面的例子中,您只指定了一个最小间距,这将导致自动布局引擎发现以下任何约束解决方案对 400pt 超级视图有效:

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

这可能不是您想要的。更重要的是,视图的宽度可以在 0-576pt 之间,这也可能不是您想要的。由于自动布局不知道您想要什么,它只是使用视图的intrinsicContentSize 来实现具体的尺寸约束。由于您选择 32pt 作为间距,第一步是给间距约束一些更实质性的指令,即告诉系统视图边缘和父视图边缘之间的间距应该是 32pts 除非视图的宽度>576pts。你会在你的 VFL 字符串中这样做:

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

这表示:“viewToAdd 的最大宽度应为 576pts,并且在其自身与其父视图之间有 32pts 的填充。如果父视图的大小超过了viewToAdd 的最大宽度加上 64pts 的初始填充,两侧的填充应该增长,以便继续解决约束集。”

这导致以下约束对于 400pt 超级视图是正确的:

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

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

【讨论】:

看来我可能不正确地说您可以简单地将选项 NSLayoutFormatAlignAllCenterX 传递给可视格式并使其在超级视图中居中。这些选项仅适用于您在可视格式字符串中明确引用的视图。所以看起来你必须有另一个明确的约束,将视图的中心约束到超级视图的中心。 是的,谢谢 - 实际上我已经将它集中在一个单独的约束中:[self.scrollViewContainer addConstraint:[NSLayoutConstraint constraintWithItem:viewToAdd attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.scrollViewContainer attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];【参考方案2】:

不确定这是否能准确回答问题,但对于那些使用 Storyboard 的人:我发现您可以为父视图左侧和右侧的距离添加宽度约束和约束。如果您随后将宽度约束更改为 '

【讨论】:

以上是关于在 iOS 上使用自动布局如何指定视图应占用尽可能多的空间?的主要内容,如果未能解决你的问题,请参考以下文章

使用自动布局更改方向时更改内容顺序

自动布局视图以占用所有可用空间

尝试理解 iOS 8 中的 UIScrollView 自动布局

如何在 ios 中使用自动布局更改滚动视图内容大小

如何使用堆栈视图自动布局标签和按钮?

如何使用自动布局对子视图进行编程以占用其父视图宽度的 50% 但保持恒定高度?