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

iOS自动布局:为什么不允许零乘数?,ios,autolayout,nslayoutconstraint,Ios,Autolayout,Nslayoutconstraint,我正在为动态创建的视图计算一些约束乘数。有时是零。发生这种情况时,我会收到以下未处理的异常: 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 根据

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

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感谢您的链接。虽然没有拍摄messenger,但苹果的声明并不完全符合Interface Builder当时让我做的事情。我使用以下方法在容器视图中定位30像素偏置的按钮3/4:

我还没有尝试0作为乘数,但是0.75也不是一个单位值。有一段时间效果不错

澄清2

@马特,这是我想做的一个例子:

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


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

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

编辑是的,现在您已经展示了更多您想要的内容,我的答案是正确的。以下是我的渲染:

黑色边框的矩形是superview,条形图的位置与superview的宽度相关,与图表一致

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


看,这个技术的一个例子,我的回答是:好的,我也做了这个作为解决方法。我真的不喜欢创建“fluff”视图,但我接受这一点。我仍然不明白为什么IB会让我在那里放一个似乎有效的非标识值。在iOS 9中,你可以使用UILayoutGuide而不是间隔视图。但这与iOS 8不向后兼容。我向你保证这是正常的。这就是他们发明UILayoutGuide的原因。为什么乘数不能是1.0,常数不能变化(即常数=m1*width)?是的,我的猜测是对的。请参阅我修改后的答案,它准确地显示了如何实现图形。
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