具有常数的高度约束不是“稳定的”

时间:2013-12-04 13:26:39

标签: ios iphone objective-c ipad autolayout

我正在添加一个高度限制(设置为 300px ),如下所示:

    [parentView_ addConstraints:@[
          [NSLayoutConstraint constraintWithItem:containerView_ 
                              attribute:NSLayoutAttributeHeight
                              relatedBy:NSLayoutRelationEqual
                              toItem:nil attribute:NSLayoutAttributeNotAnAttribute
                              multiplier:1.0f constant:300],
          ]];

parentView_有一个名为containerView_的子视图。

containerView_有两个子视图:view1view2

然后我添加了一个按钮,一旦点击就会调用以下函数:

    [containerView_ removeConstraints:[containerView_ constraints]];
    [containerView_ addConstraints:@[
          [NSLayoutConstraint constraintWithItem:view1 
                              attribute:NSLayoutAttributeCenterY
                              relatedBy:NSLayoutRelationEqual
                              toItem:view2 attribute:NSLayoutAttributeBottom
                              multiplier:someVal1 constant:someVal2],
          ]];

someVal1someVal2在点击与点按之间切换(我正在控制值)。

问题:

在第一次点击期间,containerView_的高度从300变为299(randomaly!),然后又变回300并且看起来不太好(看起来视图正在增长和缩小)。

我已通过覆盖layoutSubviews并打印containerView_的框架来验证这一点。

可能导致身高从300变为299,即使我设置了 300 的禁令(还有别的!)

1 个答案:

答案 0 :(得分:0)

示例项目包含已应用的约束的完整列表,其中包括:

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)