Je sais que beaucoup de gens ont déjà posé des tonnes de questions à ce sujet, mais même avec les réponses, je ne peux pas le faire fonctionner.
Quand je suis confronté à des contraintes sur le storyboard, c'est facile mais dans le code j'ai du mal. J'essaye, par exemple, d'avoir une vue qui reste sur le côté droit et a la hauteur de l'écran en fonction de l'orientation de l'écran. Voici mon code:
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 748)];
myView.backgroundColor = [UIColor redColor];
[self.view addSubview:myView];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-[myView(>=748)]-|"
options:0 metrics:nil
views:NSDictionaryOfVariableBindings(myView)]];
Cela ne satisfait pas certaines contraintes. Je ne vois pas ce qui ne va pas. Aussi, pourquoi ne puis-je pas utiliser une propriété comme self.myView
au lieu d'une variable locale comme myView
?
objective-c
ios
constraints
autolayout
pierre23
la source
la source
myView
? (3) Qu'est-ce quevivi
(comme l'ACB l'a demandé)? (4) Avez-vous une propriétémyView
déclarée surself
?Réponses:
Lors de l'utilisation de la disposition automatique dans le code, la définition du cadre ne fait rien. Donc, le fait que vous ayez spécifié une largeur de 200 sur la vue ci-dessus ne veut rien dire lorsque vous définissez des contraintes dessus. Pour que l'ensemble de contraintes d'une vue soit sans ambiguïté, il lui faut quatre choses: une position x, une position y, une largeur et une hauteur pour un état donné.
Actuellement dans le code ci-dessus, vous n'en avez que deux (hauteur, par rapport à la vue supervisée, et position y, par rapport à la vue supervisée). En plus de cela, vous avez deux contraintes requises qui peuvent entrer en conflit en fonction de la configuration des contraintes de la vue supervisée de la vue. Si le superview devait avoir une contrainte obligatoire qui spécifie que sa hauteur est une valeur inférieure à 748, vous obtiendrez une exception "contraintes non satisfaites".
Le fait que vous ayez défini la largeur de la vue avant de définir des contraintes ne signifie rien. Il ne prendra même pas en compte l'ancien cadre et calculera un nouveau cadre en fonction de toutes les contraintes qu'il a spécifiées pour ces vues. Lorsque je traite de la mise en page automatique dans le code, je crée généralement une nouvelle vue en utilisant
initWithFrame:CGRectZero
ou simplementinit
.Pour créer le jeu de contraintes requis pour la mise en page que vous avez décrite verbalement dans votre question, vous devez ajouter des contraintes horizontales pour délimiter la largeur et la position x afin de donner une mise en page entièrement spécifiée:
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[myView(>=748)]-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(myView)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[myView(==200)]-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(myView)]];
La description verbale de cette disposition se lit comme suit en commençant par la contrainte verticale:
Si vous souhaitez simplement que la vue remplisse toute la hauteur de la vue supervisée sans contraindre la hauteur de la vue supervisée, vous omettez simplement le
(>=748)
paramètre dans le texte au format visuel. Si vous pensez que le(>=748)
paramètre est nécessaire pour lui donner une hauteur - vous ne le faites pas dans ce cas: épingler la vue sur les bords de la vue supervisée en utilisant la syntaxe bar (|
) ou bar avec espace (|-
,-|
), vous donnez à votre vue un y -position (épinglant la vue sur un seul bord), et une position y avec la hauteur (épinglant la vue sur les deux bords), satisfaisant ainsi votre jeu de contraintes pour la vue.En ce qui concerne votre deuxième question:
En utilisant
NSDictionaryOfVariableBindings(self.myView)
(si vous aviez une configuration de propriété pour myView) et en l'introduisant dans votre VFL à utiliserself.myView
dans votre texte VFL, vous obtiendrez probablement une exception lorsque la mise en page automatique essaiera d'analyser votre texte VFL. Cela a à voir avec la notation par points dans les clés du dictionnaire et le système essayant d'utiliservalueForKeyPath:
. Voir ici pour une question et une réponse similaires .la source
Salut, j'utilise beaucoup cette page pour les contraintes et le "comment faire". Il m'a fallu une éternité pour arriver au point de réaliser que j'avais besoin:
myView.translatesAutoresizingMaskIntoConstraints = NO;
pour que cet exemple fonctionne. Merci Userxxx, Rob M. et surtout larsacus pour l'explication et le code ici, cela a été inestimable.
Voici le code complet pour obtenir les exemples ci-dessus à exécuter:
UIView *myView = [[UIView alloc] init]; myView.backgroundColor = [UIColor redColor]; myView.translatesAutoresizingMaskIntoConstraints = NO; //This part hung me up [self.view addSubview:myView]; //needed to make smaller for iPhone 4 dev here, so >=200 instead of 748 [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[myView(>=200)]-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(myView)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[myView(==200)]-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(myView)]];
la source
Version Swift
Mis à jour pour Swift 3
Cet exemple montre deux méthodes pour ajouter par programme les contraintes suivantes de la même manière que si vous le faisiez dans Interface Builder:
Largeur et hauteur
Centrer dans le conteneur
Code de la chaudière
override func viewDidLoad() { super.viewDidLoad() // set up the view let myView = UIView() myView.backgroundColor = UIColor.blue myView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(myView) // Add constraints code here (choose one of the methods below) // ... }
Méthode 1: Style d'ancrage
// width and height myView.widthAnchor.constraint(equalToConstant: 200).isActive = true myView.heightAnchor.constraint(equalToConstant: 100).isActive = true // center in container myView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true myView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
Méthode 2: Style NSLayoutConstraint
// width and height NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 200).isActive = true NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 100).isActive = true // center in container NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0).isActive = true NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0).isActive = true
Remarques
NSLayoutConstraint
style, mais il n'est disponible qu'à partir d'iOS 9, donc si vous prenez en charge iOS 8, vous devez toujours utiliserNSLayoutConstraint
Style.la source
Concernant votre deuxième question sur les propriétés, vous ne pouvez l'utiliser
self.myView
que si vous l'avez déclarée comme propriété en classe. Puisqu'ilmyView
s'agit d'une variable locale, vous ne pouvez pas l'utiliser de cette façon. Pour plus de détails à ce sujet, je vous recommande de parcourir la documentation Apple sur les propriétés déclarées ,la source
pourquoi ne puis-je pas utiliser une propriété comme
self.myView
au lieu d'une variable locale comme myView?essayez d'utiliser:
NSDictionaryOfVariableBindings(_view)
au lieu de
self.view
la source
Veuillez également noter qu'à partir d'iOS9, nous pouvons définir des contraintes par programmation «plus concises et plus faciles à lire» en utilisant des sous-classes de la nouvelle classe d'assistance NSLayoutAnchor .
Un exemple de la doc:
[self.cancelButton.leadingAnchor constraintEqualToAnchor:self.saveButton.trailingAnchor constant: 8.0].active = true;
la source