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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30620016/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 06:12:09  来源:igfitidea点击:

How to change or update NSLayoutConstraint programmatically

iosobjective-cnslayoutconstraint

提问by Nijat2018

I have implemented AutoLayout programmatically using the Code :

我已经使用代码以编程方式实现了 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];
}

And this works perfect, but every-time this ViewController receives a Notification, it will run:

这很完美,但是每次这个 ViewController 收到一个Notification 时,它都会运行:

[self.view layoutIfNeeded];

But I want to set the width of listViewNavigation according a boolean variable 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;
    }

But i do not know how can I update the NSLayoutConstraint :

但我不知道如何更新 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];

when this ViewController receive the notification.

当这个 ViewController 收到通知时

采纳答案by Nijat2018

OK, I figure out.

好的,我知道了。

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

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

回答by Leo

I think you have 2 options.

我认为你有 2 个选择。

Option 1Keep a property

选项 1保留财产

@property (strong,nonatomic)NSLayoutConstraint *constraintToAnimate3;

Then use this property to

然后使用这个属性

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];

When you want to change

当你想改变

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];
}];

Option 2Set an identifier of constraintToAnimate3

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

constraintToAnimate3.identifier = @"1234"

Then search to get the constraint

然后搜索以获取约束

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

Then change the constant as shown in Option1

然后更改常量,如 Option1 所示

Update:If use constant in the code I post

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

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

回答by gnasher729

It's essential that you don't just add the constraints to your view, but that you also remember them.

重要的是,您不仅要向视图添加约束,还要记住它们。

It's easiest to change a constraint if you only need to change its constant - the constant is the only part of a constraint that can be changed later repeatedly. To do that, you need to store the constraint on its own.

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

Otherwise you need to remove old constraints and add new ones. Since you usually have more than one constraint, store arrays with sets of constraints that may need to be replaced, then update the whole array. You can also use the activateConstraints and deactivateConstraints methods.

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