如何将 AutoLayout 约束的常量设置为超级视图的百分比?

Posted

技术标签:

【中文标题】如何将 AutoLayout 约束的常量设置为超级视图的百分比?【英文标题】:How can I set AutoLayout constraints' constant as a percentage of the superview? 【发布时间】:2018-10-19 12:46:31 【问题描述】:

我正在开展一个需要创建可自定义共享卡的项目(了解人们可以导出以稍后在社交媒体上共享的图像)。

我将这些共享卡构建为包含其他几个 UI 元素(主要是 UIImageViews 和 UILabels)的普通 UIView。

为简单起见,我们将其称为 SharingCardView

由于此视觉对象将被导出和共享,因此我需要让它在所有设备上看起来都完全相同。所以我的理解是,我需要让 AutoLayout 约束具有基于用户设备屏幕尺寸的响应常量。

假设我在 iPhone 上显示 UIView,然后在 iPad 上显示,我希望保持 SharingCardView 内所有内容的纵横比,这样人们就看不到从iPhone 或 iPad。

### 问题:

我希望能够将标签固定到 SharingCardView 的顶部 **具有 10% 的常数**,如下面的屏幕截图所示。

###到目前为止,我尝试过这种方式

我尝试将常量设置为 self.bounds.width * 0.1 但当我创建视图时,边界显然等于零,因此约束只是将所有内容固定在最顶部而没有任何填充。

nowUpOnYTLbl.anchor(top: topAnchor,
                            left: leftAnchor,
                            bottom: nil,
                            right: rightAnchor,
                            paddingTop: self.bounds.width * 0.1,
                            paddingLeft: 30,
                            paddingBottom: 0,
                            paddingRight: 30,
                            width: 0,
                            height: 20
        )

任何建议都会非常有帮助。如果您认为这种方法是完全错误的,那么我完全愿意寻找替代解决方案。

【问题讨论】:

【参考方案1】:

不要使用框架/边界来设置约束!仅使用约束关系来设置约束。所以在这里,你希望这个顶部约束是超级视图高度约束的 1/10。这样,该比率将是实时,在运行时取决于超级视图的实际高度。

但是,您不能这样做,因为您只能在一个高度约束和另一个高度约束之间形成这种比率。

因此,您将不得不使用一个不可见的间隔视图,其高度约束是父视图高度约束的 1/10(即高度约束相等,multiplier0.1)。 我可以很容易地在 Interface Builder 中实现这一点,而无需任何代码。在我的屏幕截图中,不可见的间隔视图是可见的,因此您可以看到窗帘后面的人......!

【讨论】:

我从没想过为此使用不可见的视图。这很聪明。我会测试一下;)谢谢马特! 如果您决定全部在代码中完成,您可以使用不可见的 UILayoutGuide 对象而不是 UIView 空间视图。这样做更好,因为它减少了渲染引擎的开销。 这样做会不会降低性能,尤其是如果操作需要,您需要对许多项目重复它 @Sh_Khan 不,这就是堆栈视图的工作方式(不可见的 UILayoutGuides 作为分隔符)。还有一个最近的 WWDC 视频(我认为是 2017 年),当你在 Interface Builder 中执行此操作时,Apple 实际上推荐了这个技巧。 出于同样的原因,如果在 IB 中执行此操作,则(空)堆栈视图比不可见视图更好【参考方案2】:

您可以通过使标签的顶部约束与共享视图的 centerY 相关来实现这一点

你给 shareView 一个与它的 superView 成比例的大小,所以在不同的设备上运行时 centerY 的值会有所不同,假设你想把这个常数设为 share view height 的 1/10,那么你就这样做

topConstraintOfLabel = (centerYOfShareView * 2) * 1/10

=

topConstraintOfLabel = centerYOfShareView * 1/5

我这样做是因为我们不能用 height 约束顶部约束,所以我们使用 centerY 并将我们想要的方面加倍为 centerY = 0.5 * height ,同样的事情也适用于 centerX 的前导/尾随

【讨论】:

【参考方案3】:

您可以使用视图并通过使用乘数为超级视图中的视图分配空间。因此,当您的超级视图大小更改时,视图会根据乘数自动更改其大小。

【讨论】:

但不清楚,因为您没有包括尺寸乘数部分 是的,我确实包含了它。比率意味着乘数。不过,我会按照您的建议进行澄清。

以上是关于如何将 AutoLayout 约束的常量设置为超级视图的百分比?的主要内容,如果未能解决你的问题,请参考以下文章

Xcode Autolayout - 约束等于另一个约束

AutoLayout常量更改不动画

自动布局约束不会设置为 SuperView 的边缘 [重复]

如何设置纵向和横向约束

以 Autolayout 视觉形式调整子视图的大小

同时使用不同的动画曲线为 AutoLayout 约束设置动画