web-dev-qa-db-fra.com

Création de contraintes de disposition automatique pour topLayoutGuide et bottomLayoutGuide dans le code

documentation d'Apple sur la création de contraintes de disposition automatique entre une vue et l'un des guides de disposition ne montre qu'un exemple utilisant VFL .

Existe-t-il un moyen de créer ces contraintes par programme sans VFL (en utilisant l'autre API de NSLayoutConstraint ou similaire)?

(Remarque: je demande spécifiquement de le faire dans le code, pas dans Interface Builder. Et je ne veux pas que le length calculé du jeu de guides soit une constante statique sur une contrainte, je veux une contrainte où les modifications de la longueur du guide de mise en page entraîneraient automatiquement le réglage de la position de la vue contrainte.)

64
smileyborg

Pour un UIButton que vous souhaitez placer 20 points en dessous du UIViewController.topLayoutGuide vous créez le NSLayoutConstraint comme ceci:

[NSLayoutConstraint constraintWithItem:self.button
                             attribute:NSLayoutAttributeTop
                             relatedBy:NSLayoutRelationEqual
                                toItem:self.topLayoutGuide
                             attribute:NSLayoutAttributeBottom
                            multiplier:1.0
                              constant:20.0];

Avec iOS 9, vous pouvez également créer le NSLayoutConstraint de cette façon:

[self.button.topAnchor constraintEqualToAnchor:self.topLayoutGuide.bottomAnchor
                                      constant:20.0];
93
Jamie McDaniel

Pour compléter la réponse de @ JamieMcDaniel, la version Swift + iOS9 serait:

self.button.topAnchor
    .constraintEqualToAnchor( self.topLayoutGuide.bottomAnchor ).active = true

N'oubliez pas le .active = true part car sinon la contrainte ne se déclenche pas automatiquement.

6
SuitedSloth

Juste un ajout à @Jamie McDaniel, au cas où ce ne serait pas immédiatement évident, vous devez ajouter la contrainte qu'il suggère de créer:

NSLayoutConstraint *buttonTopConstraint = [NSLayoutConstraint constraintWithItem:self.button
                                 attribute:NSLayoutAttributeTop
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.topLayoutGuide
                                 attribute:NSLayoutAttributeBottom
                                multiplier:1.0
                                  constant:20.0];
[self.view addConstraint:buttonTopConstraint];
3
Alex Y

Ceci est un Gist que j'ai créé, vous êtes censé incorporer toutes vos sous-vues dans une vue de réservoir (vue de conteneur) ajoutée dans un xib, il supprime les contraintes de vue de réservoir-vue d'ensemble xib et ajoute une contrainte supérieure to topLayoutGuide donnant un look iOS6. Cela pourrait être intéressant pour ce que vous voulez réaliser.

//This should be added before the layout of the view
- (void) adaptToTopLayoutGuide {
    //Check if we can get the top layoutguide
    if (![self respondsToSelector:@selector(topLayoutGuide)]) {
        return;
    }
    //tankView is a contaner view
    NSArray * array = [self.tankView referencingConstraintsInSuperviews]; //<--For this method get the Autolayout Demistified Book Sample made by Erica Sadun
    [self.view removeConstraints:array];
    NSArray * constraintsVertical = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[topLayoutGuide]-0-[tankView]|" options:0 metrics:nil views:@{@"tankView": self.tankView, @"topLayoutGuide":self.topLayoutGuide}];
    [self.view addConstraints:constraintsVertical];
    NSArray * constraintsHorizontal = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[tankView]|" options:0 metrics:nil views:@{@"tankView": self.tankView}];
    [self.view addConstraints:constraintsHorizontal];

}
3
Andrea