设置后NSLayoutConstraint常量不更新

Ram*_*har 21 objective-c uiviewanimation ios nslayoutconstraint

我有一个UIView带有相应xib文件的子类.在我的xib中,我有一个NSLayoutConstraint属性,我正在尝试动画.我有一个animateIn方法.问题是只有animateIn方法有效.当我尝试再次更新常量时,它只是保持在前一个值.

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *horizontalConstraint;
Run Code Online (Sandbox Code Playgroud)

按下按钮后,我正在尝试更新常量.但是在设置之后,常量似乎没有更新.即使将其设置为-500,它仍然会记录0.我正在打电话layoutIfNeeded但没有任何反应.

// this works
- (void) animateIn { 
    [UIView animateWithDuration:1.0 delay:2.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        self.alpha = 1.0;
    } completion:^(BOOL finished) {

        [UIView animateWithDuration:1.0 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            self.horizontalConstraint.constant = 0;
            [self layoutIfNeeded];
        } completion:^(BOOL finished) {
        }];
    }];
}

// this does not work
- (IBAction)resume:(id)sender {
        self.horizontalConstraint.constant = -500;
        [self layoutIfNeeded];

        NSLog(@"%f",self.horizontalConstraint.constant); // this always stays 0
    }
Run Code Online (Sandbox Code Playgroud)

UPDATE

当我想第二次使用它时,我的NSLayoutConstraint似乎是(null).这可以解释为什么它没有更新.我应该如何保留它的参考?

Yog*_*har 49

您需要调用NSLayoutConstraint所setNeedsUpdateConstraints针对的相应方法UIView(control)来更新约束.

例如UIButton

self.buttonConstraint.constant = 55;
[self.btnTest setNeedsUpdateConstraints];
Run Code Online (Sandbox Code Playgroud)

在你的情况下

[self setNeedsUpdateConstraints];
Run Code Online (Sandbox Code Playgroud)

  • 这是不正确的.当你需要更新它们时,你应该调用`setNeedsUpdateConstraints`,然后在自动调用的`updateViewConstraints`方法中更改`constant`.或者,您可以在需要它的方法中更改常量(以保持代码更紧密地链接),然后在约束的视图的`superview`上调用`setNeedsLayout`. (2认同)
  • 我不同意您在这里的描述。您可以*覆盖`updateConstraints()`以简化一组复杂的批处理更改。但是,从[documentation](https://developer.apple.com/reference/uikit/uiview/1622512-updateconstraints)中:>在影响更改发生后,立即更新约束几乎总是更干净,更容易。...>仅当在适当位置更改约束太慢或视图产生大量冗余更改时,才应覆盖此方法。 (2认同)

Fré*_*dda 10

你确定这个约束在某个地方没有被激活吗?将约束的"active"属性设置为false会导致视图层次结构删除约束.如果您还没有对它的引用,则约束对象将从内存中删除.

我和你有同样的问题,并删除了"弱",因此约束现在是一个强大的属性.因此,在取消激活时它不会设置为nil(因为我的视图控制器总是有一个强指针),我可以重新激活它并重新设置它的常量.

// NB: don't create these contraints outlets as "weak" if you intend to de-activate them, otherwise they would be set to nil when deactivated!
@IBOutlet private var captionViewHeightConstraint: NSLayoutConstraint!
Run Code Online (Sandbox Code Playgroud)


小智 9

我遇到一个问题,我第一次在代码中设置约束常量时,将设置常量,但是在调用layoutIfNeeded()之后,如下所示:

myConstraint.constant = newValue;
[view layoutIfNeeded]
Run Code Online (Sandbox Code Playgroud)

该常数将返回到原始值!我可以在调试器中看到值更改。

我终于发现这是因为,在情节提要中,我对常数进行了设置。例如:

在此处输入图片说明

一旦删除变化,约束常量值就不会通过layoutIfNeeded调用变回原始值。


Bog*_*lea 5

当您完成约束更改时,只需调用:

[self setNeedsUpdateConstraints];
Run Code Online (Sandbox Code Playgroud)