web-dev-qa-db-fra.com

Comment modifier ou mettre à jour NSLayoutConstraint par programme

J'ai implémenté AutoLayout par programmation en utilisant le code:

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

Et cela fonctionne parfaitement, mais chaque fois que ce ViewController reçoit un Notification, il s'exécutera:

[self.view layoutIfNeeded];

Mais je veux définir la largeur de listViewNavigation en fonction d'une variable booléenne connectée.

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

Mais je ne sais pas comment mettre à jour 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];

lorsque ce ViewController reçoit la notification.

17
Nijat2018

OK, je comprends.

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

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

Je pense que vous avez 2 options.

Option 1 Conserver une propriété

@property (strong,nonatomic)NSLayoutConstraint *constraintToAnimate3;

Utilisez ensuite cette propriété pour

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

Quand tu veux changer

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 2 Définissez un identifiant de constraintToAnimate3

constraintToAnimate3.identifier = @"1234"

Ensuite, recherchez pour obtenir la contrainte

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

Modifiez ensuite la constante comme indiqué dans l'Option1

Mise à jour: Si utiliser constante dans le code que je poste

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

Il est essentiel que vous n'ajoutiez pas seulement les contraintes à votre vue, mais que vous vous en souveniez également.

Il est plus facile de changer une contrainte si vous avez seulement besoin de changer sa constante - la constante est la seule partie d'une contrainte qui peut être modifiée plus tard à plusieurs reprises. Pour ce faire, vous devez stocker la contrainte seule.

Sinon, vous devez supprimer les anciennes contraintes et en ajouter de nouvelles. Étant donné que vous avez généralement plusieurs contraintes, stockez les tableaux avec des ensembles de contraintes qui peuvent devoir être remplacés, puis mettez à jour l'ensemble du tableau. Vous pouvez également utiliser les méthodes activateConstraints et deactivateConstraints.

1
gnasher729