Подтвердить что ты не робот

Как изменить или обновить NSLayoutConstraint программно

Я реализовал 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];
}

И это работает отлично, но каждый раз, когда этот ViewController получает Уведомление, он будет запускаться:

[self.view layoutIfNeeded];

Но я хочу установить ширину 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];

когда этот ViewController получает уведомление.

4b9b3361

Ответ 1

ОК, я выясню.

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

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

Ответ 2

Я думаю, у вас есть 2 варианта.

Вариант 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 Установите идентификатор ограниченияToAnimate3

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

Update: Если использование константы в коде, я отправляю

PreView.frame.size.with = self.view.size.width * множитель + константа

Ответ 3

Важно, чтобы вы не просто добавляли ограничения в свой вид, но и помнили их.

Легче всего изменить ограничение, если вам нужно только изменить его константу - константа является единственной частью ограничения, которую можно изменить несколько раз. Для этого вам нужно сохранить ограничение самостоятельно.

В противном случае вам нужно удалить старые ограничения и добавить новые. Поскольку вы обычно имеете более одного ограничения, храните массивы с наборами ограничений, которые могут потребоваться заменить, а затем обновите весь массив. Вы также можете использовать методы activateConstraints и deactivateConstraints.