具有常数的高度约束不是“稳定的”
Posted
技术标签:
【中文标题】具有常数的高度约束不是“稳定的”【英文标题】:Height constraint with a constant is not "stable" 【发布时间】:2013-12-04 13:26:39 【问题描述】:我正在添加一个高度限制(设置为 300px),如下所示:
[parentView_ addConstraints:@[
[NSLayoutConstraint constraintWithItem:containerView_
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0f constant:300],
]];
parentView_
有一个名为containerView_
的子视图。
containerView_
有两个子视图:view1
和 view2
然后我添加按钮,一旦点击就会调用以下功能:
[containerView_ removeConstraints:[containerView_ constraints]];
[containerView_ addConstraints:@[
[NSLayoutConstraint constraintWithItem:view1
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:view2 attribute:NSLayoutAttributeBottom
multiplier:someVal1 constant:someVal2],
]];
someVal1
和 someVal2
在点击之间切换(我正在控制值)。
问题:
在第一次点击期间,containerView_ 的高度从 300 变为 299(随机!),然后又回到 300 并且看起来不太好(看起来视图在增长和缩小)。
我已通过覆盖 layoutSubviews
并打印 containerView_
的框架来验证这一点。
什么可能导致高度从 300 变为 299,即使我设置了 300(仅此而已!)的约束?
【问题讨论】:
你能发布一个展示这个问题的示例项目吗? @ArkadiuszHolko 示例项目可以在here 找到。它可能不会在第一次运行时重现,所以给它几张照片,直到你在控制台中看到“检测到错误的高度” @ArkadiuszHolko 忘了说:右边有一个蓝色的 UISlider - 尝试移动它,它会触发约束移除/添加,从而导致高度发生变化。 @ArkadiuszHolko 问题解决了 :-) 【参考方案1】:示例项目包含已应用的约束的完整列表,其中包括:
SampleSlider.m:59
[NSLayoutConstraint constraintWithItem:slider_ attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual
toItem:self attribute:NSLayoutAttributeCenterY
multiplier:1.0 constant:0]
将此约束更改为
[NSLayoutConstraint constraintWithItem:slider_ attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual
toItem:self attribute:NSLayoutAttributeBottom
multiplier:1.0 constant:0]
解决了这个问题。它显示为 CenterY 约束不精确,或者在每次运行时将 floor()'d/ceil()'d 设置为不同的值。
我发现的有趣的事情如下:在两次不同的运行中,我打印出了框架(他的身高应该是 300):
<SampleSlider: 0x8988bd0; frame = (12 -1; 56 301); layer = <CALayer: 0x894e4b0>>
<SampleSlider: 0x894f260; frame = (12 1; 56 299); layer = <CALayer: 0x894b770>>
注意 y 位置 - 它不是稳定在 0,而是跳到 -1, 1 分别与高度 (301, 299) 一起。抛开 y 定位问题,真正令人烦恼的是框架的高度:
虽然使用了以下线性方程(或者看起来如此?),但它无论如何都不满足约束:
frameHeight = constraintHeight - y
如:
301 = 300 - (-1)
(所以实际高度是 abs(-1) + 301 = 302)
对于上面的第一帧,以及,
299 = 300 - 1
(所以实际高度是 299 - 1 = 298)
对于第二帧。 闻起来很有趣,不是吗?好像有人犯了一个错误,减去了 y 值而不是添加它。
将方程(假设意义)更改为
frameHeight = constraintHeight + y
产量
frameHeight = 300 + -1 = 299
对于第一帧,所以实际高度现在是 300(y = -1,h = 299)
frameHeight = 300 + 1 = 301
对于第二帧,所以实际高度又是 300 (y = 1, h = 301)
【讨论】:
以上是关于具有常数的高度约束不是“稳定的”的主要内容,如果未能解决你的问题,请参考以下文章