如何以编程方式更改或更新NSLayoutConstraint

21
我已经使用以下代码以编程方式实现了AutoLayout:

我已以编程方式实现了AutoLayout:

- (void)addConstraintWithListNavigationViewController:(UIView *)listViewNavigation y:(CGFloat)y height:(CGFloat)height
{
    //WIDTH_ListTableView = 0.4

    //set x = 0;
    NSLayoutConstraint *constraintToAnimate1 = [NSLayoutConstraint constraintWithItem:listViewNavigation
                                                                            attribute:NSLayoutAttributeLeft
                                                                            relatedBy:NSLayoutRelationEqual
                                                                               toItem:self.view
                                                                            attribute:NSLayoutAttributeLeft
                                                                           multiplier:0.00
                                                                             constant:0];
    [self.view addConstraint:constraintToAnimate1];


    //set y = y;
    NSLayoutConstraint *constraintToAnimate2 = [NSLayoutConstraint constraintWithItem:listViewNavigation
                                                                            attribute:NSLayoutAttributeTop
                                                                            relatedBy:NSLayoutRelationEqual
                                                                               toItem:self.view
                                                                            attribute:NSLayoutAttributeBottom
                                                                           multiplier:0.00
                                                                             constant:y];
    [self.view addConstraint:constraintToAnimate2];








    //set Width = self.view.frame.size.width*0.4
    NSLayoutConstraint *constraintToAnimate3 = [NSLayoutConstraint constraintWithItem:listViewNavigation
                                                                            attribute:NSLayoutAttributeWidth
                                                                            relatedBy:NSLayoutRelationEqual
                                                                               toItem:self.view
                                                                            attribute:NSLayoutAttributeWidth
                                                                           multiplier:1-WIDTH_ListTableView
                                                                             constant:0.0];
    [self.view addConstraint:constraintToAnimate3];





    //Set height = height
    NSLayoutConstraint *constraintToAnimate4 = [NSLayoutConstraint constraintWithItem:listViewNavigation
                                                                            attribute:NSLayoutAttributeHeight
                                                                            relatedBy:NSLayoutRelationEqual
                                                                               toItem:nil
                                                                            attribute:NSLayoutAttributeNotAnAttribute
                                                                           multiplier:0.00
                                                                             constant:height];
    [self.view addConstraint:constraintToAnimate4];
}

这个方案非常完美,但每当这个视图控制器接收到一个通知时,它都会运行:

[self.view layoutIfNeeded];

但是我想根据一个布尔变量connected设置listViewNavigation的宽度。

if(connected){
        listViewNavigation.view.frame.size.width = 0.4 * self.view.frame.size.width;
    }
    else{
        listViewNavigation.view.frame.size.width = 0.6 * self.view.frame.size.width;
    }

但我不知道如何更新NSLayoutConstraint:

NSLayoutConstraint *constraintToAnimate3 = [NSLayoutConstraint constraintWithItem:PreView
                                                                            attribute:NSLayoutAttributeWidth
                                                                            relatedBy:NSLayoutRelationEqual
                                                                               toItem:self.view
                                                                            attribute:NSLayoutAttributeWidth
                                                                           multiplier:1 - WIDTH_ListTableView
                                                                             constant:0.0];
[self.view addConstraint:constraintToAnimate3];

当这个视图控制器接收到通知时。

3个回答

22

我认为你有两个选择。

选择1 保留一处财产。

@property (strong,nonatomic)NSLayoutConstraint *constraintToAnimate3;

然后使用这个属性来

self.constraintToAnimate3 = [NSLayoutConstraint constraintWithItem:PreView
                                                                        attribute:NSLayoutAttributeWidth
                                                                        relatedBy:NSLayoutRelationEqual
                                                                           toItem:self.view
                                                                        attribute:NSLayoutAttributeWidth
                                                                       multiplier:1
                                                                         constant:-1 * 0.4 * self.view.frame.size.width];
[self.view addConstraint:self.constraintToAnimate3];

当你想要改变的时候

if(connected){
    self.constraintToAnimate3.constant = -1 *0.6 * self.view.frame.size.width;
}
else{
    self.constraintToAnimate3.constant = -1 *0.4 * self.view.frame.size.width;
}
[UIView animateWithDuration:yourduration animations:^{    [self.view layoutIfNeeded];
}];

选项2 设置一个名为constraintToAnimate3的标识符

constraintToAnimate3.identifier = @"1234"

然后搜索以获取约束条件

NSLayoutConstraint * constraint3 = nil;
NSArray * constraints = self.view.constraints;
for (NSLayoutConstraint * constraint in constraints) {
    if ([constraint.identifier isEqualToString:@"1234"]) {
        constraint3 = constraint;
        break;
    }
}

请按照Option1所示更改常量。

更新: 如果在我发布的代码中使用常量。

PreView.frame.size.with = self.view.size.width * multiplier + constant

这样,您需要更新常量。因此,我将约束条件更改为“乘数:1,常量:0.4 * self.view.frame.size.width”,您可以根据需要将常量设置为正确的值。 - Leo
listViewNavigation.frame.size.width变得太大了。如果我把乘数设置为0,那就没问题了。但是我记得苹果不允许将乘数设置为0; - Nijat2018
所以,我认为如果我们设置“multiplier = 1.0”,我们应该将“constant = -0.4*self.view.frame.size.width”设置 - Nijat2018
是的,从您发布的代码中我没有得到有关您的视图确切大小的详细信息。它只是一个宽度的关系。您可以决定它是什么。PreView.width = self.view.width * multiplier + constant。我认为您可以理解。 - Leo

16

好的,我明白了。

[self.view removeConstraint:self.constraintOld];
[self.view addConstraint:self.constraintNew];

[UIView animateWithDuration:time animations:^{
    [self.view layoutIfNeeded];
}];

这是最好的方法,即使您正在完全编辑相同的约束条件。 - Fernando Mata

1

重要的是不仅要将约束添加到视图中,还要记住它们。

如果您只需要更改约束的常数,则最容易更改约束 - 常数是约束中唯一可以后续更改的部分。为此,您需要单独存储约束。

否则,您需要删除旧约束并添加新约束。由于通常有多个约束,请存储包含可能需要替换的约束集的数组,然后更新整个数组。您还可以使用activateConstraints和deactivateConstraints方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接