iOS自动布局:为啥不允许零乘数?

Posted

技术标签:

【中文标题】iOS自动布局:为啥不允许零乘数?【英文标题】:iOS auto layout: why is zero multiplier not allowed?iOS自动布局:为什么不允许零乘数? 【发布时间】:2016-07-18 17:29:57 【问题描述】:

我正在为动态创建的视图的约束计算一些乘数。有时它为零。发生这种情况时,我会收到以下未处理的异常:

A multiplier of 0 or a nil second item together with a location for the first attribute creates an illegal constraint of a location equal to a constant. Location attributes must be specified in pairs

从此代码:

NSLayoutConstraint(item: spanView,
    attribute: .leading,
    relatedBy: .equal,
    toItem: self.miniOnOffView,
    attribute: .trailing,
    multiplier: m1,
    constant: 0.0).isActive = true

其中 m1 = 0,spanView 已经添加为 self.miniOnOffView 的子视图。

基本上,给定 0 到 1 之间的分数,我正在尝试指定子视图前导部分的分数位置。我不明白为什么这是一个错误。为什么零是非法值?

有没有更好的解决方案?我基本上有子视图,我想相对于父视图以分数的方式定位左右,其中两者都在宽度的 0 和 1 之间。

说明 1

@Pärserk 感谢您的链接。没有射击信使,但 Apple 的声明并不完全符合 Interface Builder 将让我做的事情。我使用以下方法在容器视图中定位按钮 3/4,偏移为 30 像素:

我还没有(还)尝试将 0 作为乘数,但 0.75 也不是一个恒等值。它工作了一段时间。

说明 2

@matt,这是我正在尝试做的一个示例:

基本上,我有一个日历日视图。我正在尝试根据一天内的小数位置来定位红色和蓝色时间条(绿色注释显示近似值)。

我当然可以创建一个实现layoutSubviews() 的“布局”视图,并在那里进行所有这些比例布局,但我试图使用手头的机器,因此它会在前面更具声明性。我在 UICollectionView 中做了很多这样的事情,当我接受“使用 draw() 自己绘制”时的表现令人失望。

【问题讨论】:

为什么乘数不能为1.0,而常数变化(即常数= m1 * width)? 是的,我猜对了。请参阅我修改后的答案,它准确显示了如何实现您的图表。 【参考方案1】:

我不清楚你想要什么,但你不能在约束之间创建宽度关系,只能在视图之间创建。因此,如果您正在做我认为您想做的事情,您将需要创建一个不可见的“间隔”视图,该视图具有所需的宽度和位置来生成空间,并将您的可见子视图固定到该视图上。

编辑是的,既然你已经展示了更多你想要的东西,我的回答是正确的。这是我的渲染:

黑色边框的矩形是超级视图,条形图根据您的图表定位,相对于超级视图的宽度。

这是如何实现的?在蓝色条和红色条的左侧有不可见的间隔视图,通过它们的宽度从超级视图的左侧提供空间。因此,蓝色和红色条的水平布局来自四个宽度约束(sup 是超级视图):

spacerView1.widthAnchor.constraintEqualToAnchor(sup.widthAnchor, multiplier: 0.1).active = true
spacerView2.widthAnchor.constraintEqualToAnchor(sup.widthAnchor, multiplier: 0.25).active = true
blueView.widthAnchor.constraintEqualToAnchor(sup.widthAnchor, multiplier: 0.6-0.1).active = true
redView.widthAnchor.constraintEqualToAnchor(sup.widthAnchor, multiplier: 0.9-0.25).active = true

【讨论】:

见,这个技术的一个例子,我的答案在这里:***.com/a/20865342/341994 好的,我也这样做了。不太喜欢创建“绒毛”视图,但我接受就是这样。我仍然不明白为什么 IB 会让我在其中放置一个似乎有效的非身份值。 ios 9 中,您可以使用 UILayoutGuide 代替间隔视图。但这并不向后兼容 iOS 8。我向你保证这是正常的。这就是他们发明 UILayoutGuide 的原因。

以上是关于iOS自动布局:为啥不允许零乘数?的主要内容,如果未能解决你的问题,请参考以下文章

IOS自动布局中位置属性约束方程的非恒等式

iCarousel 自动布局乘数问题

了解自动布局中的乘数以使用相对定位

iOS 约束不允许使用乘数

iOS 自动布局约束:忽略隐藏或零尺寸视图?

为啥我会在不应为 size 类安装的约束上收到自动布局错误?