web-dev-qa-db-fra.com

Existe-t-il un moyen d'ajouter un identifiant aux contraintes de disposition automatique dans Interface Builder?

Après avoir fait une mise en page visuelle dans Interface Builder, j'ai créé quelques contraintes auxquelles je veux accéder au moment de l'exécution. Existe-t-il un moyen d'étiqueter ou d'identifier les contraintes dans Interface Builder afin qu'elles puissent être consultées plus tard?

La raison pour laquelle je veux le faire est que je dois effectuer une base de calcul sur les contraintes qui sont spécifiées visuellement. Je suis conscient que Apple a fourni le Visual Format Language et je pourrais spécifier les contraintes par programme dans un contrôleur. Je préfère ne pas utiliser cette approche pour ne pas perdre la rétroaction du temps de conception d'IB.

Éditer

Faire un point de référence a bien fonctionné, mais la question demeure.

22

Mise à jour:

Comme expliqué par Bartłomiej Semańczyk dans sa réponse , il y a maintenant un champ Identifiant visible dans le Inspector Attributes pour le NSLayoutConstraint rendant inutile d'exposer vous-même ce champ. Sélectionnez simplement la contrainte dans la vue Document Outline ou dans la vue Storyboard, puis ajoutez un identifiant dans la Inspector Attributes à droite.


Réponse antérieure:

Oui, cela peut être fait. NSLayoutConstraint possède une propriété appelée identifier qui peut être exposée dans Interface Builder et attribuée. Pour faire une démonstration, j'ai créé un Application à vue unique qui a une seule sous-vue qui est une boîte rouge. Cette sous-vue a 4 contraintes: largeur, hauteur, centrée horizontalement dans le conteneur, centrée verticalement dans le conteneur. J'ai donné à la contrainte de largeur l'identifiant redBoxWidth en procédant comme suit:

  1. Cliquez sur la contrainte de largeur dans la vue Mise en page du document. Ensuite, dans Identity Inspector sous Attributs d'exécution définis par l'utilisateur , cliquez sur + sous Chemin de clé . Changer keyPath en identificateur, changer le Type Boolean à String, et définissez la valeur sur redBoxWidth.

    naming a constraint

  2. Puis dans ViewDidLoad il est possible de trouver la contrainte par son nom et de changer sa valeur:

    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            for subview in view.subviews as [UIView] {
                for constraint in subview.constraints() as [NSLayoutConstraint] {
                    if constraint.identifier == "redBoxWidth" {
                        constraint.constant = 300
                    }
                }
            }
        }
    }
    
33
vacawama
  1. Depuis Xcode 7, vous pouvez le faire dans le storyboard:

enter image description here

  1. Cependant, si vous configurez votre contrainte dans le code, procédez comme suit:

    let constraint = NSLayoutConstraint() 
    constraint.identifier = "identifier"
    
  2. Pour ces contraintes, vous avez configuré dans le storyboard, mais vous devez définir l'identifiant dans le code:

    for subview in view.subviews {
        for constraint in subview.constraints() {
            constraint.identifier = "identifier"
        }
    }
    
13

Vous pouvez également lier la contrainte aux propriétés de votre contrôleur comme vous le faites pour tout autre composant. Faites-le simplement glisser et faites-le glisser dans votre code:

enter image description here

Et puis il sera accessible dans le code de votre contrôleur comme propriété:

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *myConstraint;

Et vous pouvez changer sa valeur par exemple:

self.myConstraint.constant=100.;
9
Volchik

Ajout juste à la réponse de @ vacawama. Vous pouvez écrire une catégorie UIView et extraire des contraintes à l'aide d'une fonction simple, par opposition aux boucles copier/coller partout où vous avez besoin de trouver une contrainte:

Fichier .h:

#import <UIKit/UIKit.h>

@interface UIView (EasyAutolayout)

-(NSLayoutConstraint *)constraintForIdentifier:(NSString *)identifier;

@end

Fichier .m:

#import "UIView+EasyAutolayout.h"

@implementation UIView (EasyAutolayout)

-(NSLayoutConstraint *)constraintForIdentifier:(NSString *)identifier {

    for (NSLayoutConstraint *constraint in self.constraints) {
        if ([constraint.identifier isEqualToString:identifier]) {
            return constraint;
        }
    }
    return nil;
}

@end
6
rebello95

Prenez l'IBOutlet de votre contrainte de disposition automatique.

Il existe une propriété appelée constante dans la classe NSLayoutConstraint.

Par exemple, vous avez pris la contrainte IBOutlet de hauteur de l'une des vues de votre IB, et vous souhaitez modifier sa hauteur par programme, tout ce que vous devez faire est:

 constraint.constant = isMoreHeight ? height1 : height2;

Après cela, vous devez mettre à jour toutes les autres vues dans la hiérarchie des vues de la vue d'ensemble. Pour ce faire, vous devrez écrire la ligne ci-dessous:

[self setLayoutIfNeeded];

Pour une meilleure expérience utilisateur, vous pouvez mettre cette ligne dans votre bloc d'animations pour des effets de transition plus fluides,

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

J'espère que cela t'aides..

5
Henit Nathwani

Et ça:

if let myconstraint = self.view.constraints.filter( { $0.identifier == "myconstraintId" }).first {
    // TODO: your code here...
}
4
Carlos Carvalho

mes deux cents pour OSX (les réponses précédentes concernent UIKit ..)

cela fonctionne aussi pour OSX:

final private func getConstraintForButton(){
    let constraints  = self.myButton.constraints
    for constraint in constraints  {
        if constraint.identifier == "redBoxWidth" {
            constraint.constant = 300
            break
        }
    }
}

Remarque: semble ne pas fonctionner sur NSView personnalisé, à la place ...

0
ingconti