iOS
Mise en page automatique
Recherche…
Introduction
La mise en forme automatique calcule dynamiquement la taille et la position de toutes les vues de votre hiérarchie de vue, en fonction des contraintes imposées à ces vues. La source
Syntaxe
- NSLayoutConstraint (item: Any, attribut: NSLayoutAttribute, relatedBy: NSLayoutRelation, toItem: Any?) Attribut: NSLayoutAttribute, multiplicateur: CGFloat, constante: CGFloat) // Créer une contraint par programme
Définition de contraintes par programmation
Exemple de code de chaudière
override func viewDidLoad() {
super.viewDidLoad()
let myView = UIView()
myView.backgroundColor = UIColor.blueColor()
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
// Add constraints code here
// ...
}
Dans les exemples ci-dessous, le style d'ancrage est la méthode préférée sur le style NSLayoutConstraint
, mais il n'est disponible qu'à partir d'iOS 9, donc si vous supportez iOS 8, vous devez toujours utiliser le style NSLayoutConstraint
.
Pinning
Style d'ancre
let margins = view.layoutMarginsGuide
myView.leadingAnchor.constraintEqualToAnchor(margins.leadingAnchor, constant: 20).active = true
- En plus de
leadingAnchor
, il existe égalementtrailingAnchor
,topAnchor
etbottomAnchor
.
NSLayoutConstraint Style
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1.0, constant: 20.0).active = true
- En plus de
.Leading
il est également.Trailing
,.Top
et.Bottom
. - En plus de
.LeadingMargin
il existe également.TrailingMargin
,.TopMargin
et.BottomMargin
.
Format de langage de format visuel
NSLayoutConstraint.constraintsWithVisualFormat("H:|-20-[myViewKey]", options: [], metrics: nil, views: ["myViewKey": myView])
Largeur et hauteur
Style d'ancre
myView.widthAnchor.constraintEqualToAnchor(nil, constant: 200).active = true
myView.heightAnchor.constraintEqualToAnchor(nil, constant: 100).active = true
NSLayoutConstraint Style
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 200).active = true
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 100).active = true
Format de langage de format visuel
NSLayoutConstraint.constraintsWithVisualFormat("H:[myViewKey(200)]", options: [], metrics: nil, views: ["myViewKey": myView])
NSLayoutConstraint.constraintsWithVisualFormat("V:[myViewKey(100)]", options: [], metrics: nil, views: ["myViewKey": myView])
Centre en conteneur
Style d'ancre
myView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor).active = true
myView.centerYAnchor.constraintEqualToAnchor(view.centerYAnchor).active = true
NSLayoutConstraint Style
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0).active = true
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0).active = true
Format de langage de format visuel
NSLayoutConstraint.constraintsWithVisualFormat("V:[viewKey]-(<=0)-[myViewKey]", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: ["myViewKey": myView, "viewKey": view])
NSLayoutConstraint.constraintsWithVisualFormat("H:[viewKey]-(<=0)-[myViewKey]", options: NSLayoutFormatOptions.AlignAllCenterY, metrics: nil, views: ["myViewKey": myView, "viewKey": view])
Comment utiliser la mise en page automatique
La mise en page automatique est utilisée pour organiser les vues de manière à leur donner une apparence agréable sur tous les périphériques et toutes les orientations. Les contraintes sont les règles qui indiquent comment tout doit être défini. Ils comprennent, entre autres, l’épinglage des bords, le centrage et la taille des paramètres.
La mise en page automatique est activée par défaut, mais vous pouvez vérifier cela deux fois. Si vous cliquez sur Main.storyboard dans le navigateur de projet, puis affichez l'inspecteur de fichiers. Assurez-vous que la mise en page automatique et les classes de taille sont cochées:
Les contraintes de présentation automatique peuvent être définies dans Interface Builder ou dans le code. Dans Interface Builder, vous trouvez les outils de mise en page automatique en bas à droite. En cliquant dessus, vous découvrirez différentes options pour définir les contraintes sur une vue.
Si vous souhaitez appliquer différentes contraintes pour différentes tailles ou orientations d'appareils, vous pouvez les définir dans les options de classe de taille disponibles dans la partie inférieure.
Contraintes Centrales
Sélectionnez votre bouton (ou la vue que vous souhaitez centrer) sur le storyboard . Cliquez ensuite sur le bouton d'alignement en bas à droite. Sélectionnez Horizontally in Container
et Vertically in Container
. Cliquez sur "Ajouter 2 contraintes".
Si cela n'était pas déjà parfaitement centré, vous devrez peut-être faire encore une chose. Cliquez sur le bouton "Mettre à jour les cadres" qui se trouve à gauche du bouton "Embed In Stack" sur la barre inférieure.
Vous pouvez également "mettre à jour les images si nécessaire" en appuyant simultanément sur ⌘ + ⌥ + = (Commande + Option et égale) après avoir sélectionné la vue, cela pourrait vous faire gagner du temps.
Maintenant, lorsque vous exécutez votre application, elle doit être centrée, quelle que soit la taille de votre appareil.
Un autre moyen de centrer les vues à l'aide d'Interface Builder consiste à effectuer un glisser-déposer par contrôle. Supposons que vous souhaitiez centrer un UILabel
dans une vue. Ouvrez la Document Outline
du Document Outline
dans votre storyboard en cliquant sur le bouton de la barre latérale en bas à gauche. Cliquez et faites glisser depuis l'étiquette vers la vue tout en maintenant la touche ctrl (contrôle) enfoncée , et une ligne bleue doit apparaître:
A la sortie, un menu d'options de contrainte apparaîtra:
Sélectionnez "Centrer horizontalement dans le conteneur" et "Centrer verticalement dans le conteneur". Mettez à jour les cadres si nécessaire, et le tour est joué! Une étiquette centrée
Vous pouvez également ajouter les contraintes par programmation. Créez les contraintes et ajoutez-les aux éléments d'interface utilisateur et aux vues souhaités, comme le décrit l'exemple suivant, où nous créons un bouton et l'alignons au centre, horizontalement et verticalement sur sa vue d'ensemble:
Objectif c
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *yourButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 18)];
[yourButton setTitle:@"Button" forState:UIControlStateNormal];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:yourButton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]]; //Align veritcally center to superView
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:yourButton attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]]; //Align horizontally center to superView
[self.view addSubview:yourButton]; //Add button to superView
}
Rapide
override func viewDidLoad()
{
super.viewDidLoad()
let yourButton: UIButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 18))
yourButton.setTitle("Button", forState: .Normal)
let centerVertically = NSLayoutConstraint(item: yourButton,
attribute: .CenterX,
relatedBy: .Equal,
toItem: view,
attribute: .CenterX,
multiplier: 1.0,
constant: 0.0)
let centerHorizontally = NSLayoutConstraint(item: yourButton,
attribute: .CenterY,
relatedBy: .Equal,
toItem: view,
attribute: .CenterY,
multiplier: 1.0,
constant: 0.0)
NSLayoutConstraint.activateConstraints([centerVertically, centerHorizontally])
}
Vues de l'espace uniformément
Il est courant de vouloir que deux vues soient côte à côte, centrées dans leur superview. La réponse commune donnée à Stack Overflow est d'incorporer ces deux vues dans un UIView
et de centrer le UIView
. Ce n'est pas nécessaire ou recommandé. De la documentation UILayoutGuide :
Il existe un certain nombre de coûts associés à l'ajout de vues factices à votre hiérarchie de vues. Tout d'abord, il y a le coût de la création et du maintien de la vue elle-même. Deuxièmement, la vue factice est un membre à part entière de la hiérarchie des vues, ce qui signifie qu'elle ajoute une surcharge à chaque tâche exécutée par la hiérarchie. Pire encore, la vue factice invisible peut intercepter les messages destinés à d'autres vues, ce qui pose des problèmes très difficiles à trouver.
Vous pouvez utiliser UILayoutGuide
pour cela, au lieu d'ajouter les boutons dans un UIView
inutile. Un UILayoutGuide
est essentiellement un espace rectangulaire pouvant interagir avec Auto Layout. Vous placez un UILayoutGuide
sur les côtés gauche et droit des boutons et définissez leur largeur pour qu’ils soient égaux. Cela permettra de centrer les boutons. Voici comment le faire en code:
Format de langage de format visuel
view.addSubview(button1)
view.addSubview(button2)
let leftSpace = UILayoutGuide()
view.addLayoutGuide(leftSpace)
let rightSpace = UILayoutGuide()
view.addLayoutGuide(rightSpace)
let views = [
"leftSpace" : leftSpace,
"button1" : button1,
"button2" : button2,
"rightSpace" : rightSpace
]
// Lay the buttons and layout guides out horizontally in a line.
// Put the layout guides on each end.
NSLayoutConstraint.activateConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[leftSpace][button1]-[button2][rightSpace]|", options: [], metrics: nil, views: views))
// Now set the layout guides widths equal, so that the space on the
// left and the right of the buttons will be equal
leftSpace.widthAnchor.constraintEqualToAnchor(rightSpace.widthAnchor).active = true
Style d'ancre
let leadingSpace = UILayoutGuide()
let trailingSpace = UILayoutGuide()
view.addLayoutGuide(leadingSpace)
view.addLayoutGuide(trailingSpace)
leadingSpace.widthAnchor.constraintEqualToAnchor(trailingSpace.widthAnchor).active = true
leadingSpace.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true
leadingSpace.trailingAnchor.constraintEqualToAnchor(button1.leadingAnchor).active = true
trailingSpace.leadingAnchor.constraintEqualToAnchor(button2.trailingAnchor).active = true
trailingSpace.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor).active = true
Vous aurez également besoin d'ajouter des contraintes verticales à cela, mais cela centrera les boutons dans la vue sans ajouter de vues "factices"! Cela évitera au système de perdre du temps CPU pour afficher ces vues "factices". Cet exemple utilise des boutons, mais vous pouvez échanger des boutons pour n'importe quelle vue sur laquelle vous souhaitez imposer des contraintes.
Si vous prenez en charge iOS 8 ou une version antérieure, la méthode la plus simple consiste à ajouter des vues factices masquées. Avec iOS 9, vous pouvez remplacer les vues factices par des guides de mise en page.
Remarque: Interface Builder ne prend pas encore en charge les guides de mise en page (Xcode 7.2.1). Donc, si vous voulez les utiliser, vous devez créer vos contraintes dans le code. Source
Taille intrinsèque UILabel
Nous devons créer une vue qui aura un préfixe d'image pour un texte. le texte peut être de longueur variable. Nous devons obtenir un résultat où Image + texte est toujours au centre d'une vue parent.
Etape 1: Créez d'abord un projet de vue unique et nommez-le comme vous le souhaitez et ouvrez la première vue du storyboard. Faites glisser une vue de taille raisonnable et définissez sa couleur d'arrière-plan sur jaune. vue devrait ressembler à quelque chose comme ça
Etape 2: Maintenant, nous allons ajouter des contraintes à la vue jaune. Pour commencer, nous allons ajouter des contraintes de largeur et de hauteur (Attendez une minute, n’avons-nous pas dit que cette vue aura une largeur dynamique? Ok, nous y reviendrons plus tard) les contraintes suivantes, comme dans l'image ci-dessous, ne se soucient pas de la valeur de largeur. Toute valeur est juste suffisante pour la largeur. Gardez-la juste assez grande pour que nous puissions ajouter des mises en page automatiques correctement.
Après avoir ajouté ces deux contraintes, vous verrez que XCode vous donne des erreurs, car l'image ci-dessous permet de les voir et de les comprendre.
Nous avons deux erreurs (rouge signifie erreur) Comme indiqué ci-dessus, revisitons la partie ambiguïté
Contraintes manquantes: Contraintes nécessaires pour: Position X: - Comme indiqué ci-dessus, nous avons donné à la vue une largeur et une hauteur pour que ses «BOUNDS» soient définis, mais nous n'avons pas donné son origine pour que son «FRAME» ne soit pas défini. Autolayout n'est pas en mesure de déterminer quelle sera la position X de notre vue jaune
Contraintes manquantes: Contraintes nécessaires pour: Position Y: - Comme nous l'avons vu plus haut, nous avons donné à la vue une largeur et une hauteur afin de définir ses «BOUNDS», mais nous n'avons pas défini son origine. Autolayout n'est pas en mesure de déterminer quelle sera la position Y de notre vue jaune. Pour résoudre ce problème, nous devons attribuer à autolayout des fonctions de résolution X et Y. Comme nous ne pouvons pas définir de cadres, nous les ferons automatiquement. image ci-dessous, je l'expliquerai plus tard
Ce que nous avons fait, c’est que nous avons ajouté un «centre vertical» et un «centre horizontal». Ces contraintes indiquent à autolayout que notre vue jaune sera toujours au centre. Horizontalement: X est déterminé avec la contrainte verticale et Y déterminé. pourrait avoir à ajuster le cadre).
Étape 3: Notre vue jaune de base est maintenant prête. Nous allons ajouter l'image de préfixe comme sous-vue de notre vue jaune avec les contraintes suivantes. Vous pouvez choisir n'importe quelle image de votre choix.
Comme nous avons une dimension fixe pour notre image de préfixe, nous aurons une hauteur de largeur fixe pour cette image. Ajoutez les contraintes et passez à l'étape suivante.
Etape 4: Ajoutez un UILabel comme sous-vue de notre vue jaune et ajoutez les contraintes suivantes
Comme vous pouvez le voir, j'ai donné seulement des contraintes relatives à notre UILabel.Son 8 points de l'image de préfixe et 0,0,0 en haut et en bas de la vue jaune.Comme nous voulons que la largeur soit dynamique, nous ne donnerons pas de contraintes de largeur ou de hauteur .
Q: Pourquoi nous ne recevons aucune erreur maintenant, nous n'avons pas donné de largeur et de hauteur? Réponse: - Nous obtenons une erreur ou un avertissement uniquement lorsque la mise en page automatique n'est pas en mesure de résoudre quelque chose qui est nécessaire pour rendre une vue à l'écran.Avec sa hauteur, sa largeur ou son origine. est bien défini autolayout est capable de calculer le cadre de notre étiquette.
Etape 5: Maintenant, si nous nous rappelons, nous nous rendrons compte que nous avons donné une vue fixe à la vue jaune mais nous voulons qu’elle soit dynamique en fonction du texte de notre étiquette. Nous modifierons donc notre contrainte de largeur de la vue jaune. est nécessaire pour résoudre l'ambiguïté, mais nous voulons qu'il soit annulé à l'exécution en fonction du contenu de UILabel. Nous allons donc sélectionner notre vue jaune et aller dans l'inspecteur Taille et réduire la priorité de la contrainte de largeur à 1 pour qu'elle soit annulée. Suivez l'image ci-dessous.
Etape 6: Nous voulons que UILabel se développe en fonction du texte et repousse notre vue en jaune.Ainsi, nous avons réduit la priorité de la largeur de la vue en jaune.Maintenant, nous allons augmenter la priorité de la résistance de compression de texte de notre UILabel. ainsi nous augmenterons la priorité de la couverture de contenu d'UILabel. Suivez l'image ci-dessous
Comme vous pouvez le constater, nous avons augmenté la priorité de mise en cache du contenu à 500 et la priorité de la résistance de compression à 751, ce qui permettra de surpasser la priorité 1 de la contrainte de largeur.
Maintenant, construisez et exécutez, vous verrez quelque chose comme suit.
Comment animer avec la mise en page automatique
Sans mise en forme automatique, l'animation est effectuée en modifiant l'image d'une vue au fil du temps. Avec la disposition automatique, les contraintes dictent le cadre de la vue, vous devez donc animer les contraintes à la place. Cette indirection rend l’animation plus difficile à visualiser.
Voici comment animer avec la mise en page automatique:
- Modifiez la constante de la contrainte après la création à l'aide d'appels périodiques (
CADisplayLink
,dispatch_source_t
,dispatch_after
,NSTimer
). Appelez ensuitelayoutIfNeeded
pour mettre à jour la contrainte. Exemple:
Objectif c:
self.someConstraint.constant = 10.0;
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
}];
Rapide:
self.someConstraint.constant = 10.0
UIView.animate(withDuration: 0.25, animations: self.view.layoutIfNeeded)
- Modifiez les contraintes et appelez
[view layoutIfNeeded]
dans un bloc d'animation. Cela interpole entre les deux positions en ignorant les contraintes pendant l'animation.
[UIView animateWithDuration:0.5 animations:^{
[view layoutIfNeeded];
}]
Changer la priorité des contraintes . Cela consomme moins de ressources processeur que l'ajout et la suppression de contraintes.
Supprimez toutes les contraintes et utilisez des masques autosizing . Pour la suite, vous devez définir
view.translatesAutoresizingMaskIntoConstraints = YES
.Utilisez des contraintes qui n'interfèrent pas avec l'animation voulue .
Utilisez une vue de conteneur . Positionnez la superview à l'aide de contraintes. Ajoutez ensuite une sous-vue avec des contraintes qui ne combattent pas l'animation, par exemple un centre par rapport à la superview. Cela décharge une partie des contraintes à la superview, afin qu'elles ne combattent pas l'animation dans la sous-vue.
Animez les calques à la place des vues . Les transformations de couche ne déclenchent pas la mise en forme automatique.
CABasicAnimation* ba = [CABasicAnimation animationWithKeyPath:@"transform"];
ba.autoreverses = YES;
ba.duration = 0.3;
ba.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.1, 1.1, 1)];
[v.layer addAnimation:ba forKey:nil];
Remplacez layoutSubviews . Appelez
[super layoutSubviews]
et affinez les contraintes.Modifier le cadre dans viewDidLayoutSubviews . La mise en forme automatique est appliquée dans
layoutSubviews
. Une fois cette opération terminée, modifiez-la dansviewDidLayoutSubviews
.Désactivez l'option Mise en forme automatique et définissez les vues manuellement. Vous pouvez faire cela en
layoutSubviews
/layout
sans appeler l'implémentation de la super classe.
Astuce: si le parent de la vue animée n'est pas interpolé (c'est-à-dire que l'animation saute du début à la fin), appelez layoutIfNeeded()
dans la vue la plus profonde qui est le parent de la vue animée (en d'autres termes: , qui n'est pas affecté par l'animation). Je ne sais pas exactement pourquoi cela fonctionne.
Résoudre les conflits de priorité de l'étiquette UILabel
Problème : lorsque vous utilisez plusieurs étiquettes dans une vue, vous obtenez peut-être un avertissement :
Comment pouvons-nous corriger cet avertissement ?
Solution : Nous calculons et définissons les priorités dans l'ordre. Les priorités doivent être différentes des étiquettes. Cela signifie que ce qui est important obtiendra une priorité plus élevée. Par exemple, dans mon cas, j'ai défini les priorités verticales de mes étiquettes comme suit:
J'ai défini la plus haute priorité pour la 1ère étiquette et la plus basse pour la 4ème.
Dans un ViewController, je pense que vous avez du mal à voir l’effet de ces priorités. Cependant, il est très clair avec UITableViewCell + estimer la hauteur de la cellule.
J'espère que cette aide
Taille UILabel & Parentview selon le texte dans UILabel
Guide étape par étape: -
Etape 1: - Définir la contrainte sur UIView
- De premier plan. 2) en haut. 3) Trailing. (De mainview)
Étape 2: - Définir la contrainte sur l’étiquette 1
- Leading 2) Top 3) Trailing (De sa superview)
Étape 3: - Définir la contrainte sur Label 2
- Leading 2) Top 3) Trailing (De sa superview)
Etape 4: - Le plus difficile consiste à donner un bas à UILabel depuis UIView.
Étape 5: - (Facultatif) Définissez la contrainte sur UIButton
- En tête 2) En bas 3) Trailing 4) Hauteur fixe (de la vue principale)
Sortie: -
Remarque: - Assurez-vous d'avoir défini le nombre de lignes = 0 dans la propriété Label.
J'espère que cette information assez pour comprendre Autoresize UIView selon la hauteur de UILabel et Autoresize UILabel Selon le texte.
Visual Basic Basics: contraintes dans le code!
HVFL est un langage conçu pour contraindre les éléments de l'interface utilisateur de manière simple et rapide. En général, VFL a un avantage sur la personnalisation de l'interface utilisateur traditionnelle dans Interface Builder, car il est beaucoup plus lisible, accessible et compact.
Voici un exemple de VFL, dans lequel trois UIViews sont contraintes de gauche à droite, remplissant superView.width
, avec aGradeView
"H:|[bgView][aGradeView(40)][bGradeView(40)]|"
Il y a deux axes dans lesquels on peut contraindre les objets d'interface utilisateur, horizontalement et verticalement.
Chaque ligne de VFL commence toujours par H:
ou V:
Si aucun n'est présent, l'option par défaut est H:
En passant, nous avons un pipeline. |
Ce symbole, ou le tuyau, fait référence à la superview. Si vous regardez de plus près l'extrait de code VFL ci-dessus, vous remarquerez deux de ces pipelines.
Cela signifie les deux extrémités horizontales de la superview, les limites extérieures et extérieures.
Ensuite, vous verrez des crochets, dans le premier ensemble de crochets, nous avons bgView
. Quand nous avons des crochets, cela fait référence à un élément d'interface utilisateur, maintenant vous pourriez vous demander comment établir un lien entre le nom et l'élément d'interface utilisateur réel, un exutoire peut-être?
Je couvrirai cela à la fin du post.
Si vous regardez la deuxième paire de crochets [aGradeView(50)]
, nous avons des parenthèses encapsulées à l'intérieur, lorsque cela est présent, il définit la largeur / hauteur en fonction des axes, qui est dans ce cas de 50 pixels en largeur.
Les premiers crochets [bgView]
n’ont pas de largeur explicitement définie, ce qui signifie qu’ils vont s’étendre le plus possible.
Bon, c'est tout pour les bases, plus sur les choses avancées dans un autre exemple.
// 1. create views UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; [self.view addSubview:blueView]; UIView *redView = [[UIView alloc] init]; redView.backgroundColor = [UIColor redColor]; [self.view addSubview:redView]; // 2. forbid Autoresizing blueView.translatesAutoresizingMaskIntoConstraints = NO; redView.translatesAutoresizingMaskIntoConstraints = NO; // 3. make contraints // horizontal NSArray *blueH = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[blueView]-20-|" options:NSLayoutFormatAlignAllLeft metrics:nil views:@{@"blueView" : blueView}]; [self.view addConstraints:blueH]; // vertical NSArray *blueVandRedV = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[blueView(50)]-20-[redView(==blueView)]" options:NSLayoutFormatAlignAllTrailing metrics:nil views:@{@"blueView" : blueView, @"redView" : redView}]; [self.view addConstraints:blueVandRedV]; NSLayoutConstraint *redW = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0]; [self.view addConstraint:redW];
Utilisation mixte de la mise en page automatique avec une mise en page non automatique
Parfois, vous pouvez vouloir effectuer des actions supplémentaires pour les calculs de mise en page automatique effectués par UIKit
lui-même.
Exemple: lorsque vous avez un UIView
avec un maskLayer
, vous devrez peut-être mettre à jour maskLayer
dès que Auto Layout modifie le frame
UIView
// CustomView.m
- (void)layoutSubviews {
[super layoutSubviews];
// now you can assume Auto Layout did its job
// you can use view's frame in your calculations
CALayer maskLayer = self.maskLayer;
maskLayer.bounds = self.bounds;
...
}
ou si vous souhaitez prendre des mesures supplémentaires pour la mise en ViewController
automatique dans ViewController
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
// now you can assume all your subviews are positioned/resized correctly
self.customView.frame = self.containerView.frame;
}
Disposition proportionnelle
Contrainte créée comme
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1.0, constant: 20.0)
ou, du point de vue mathématique:
view.attribute * multiplier + constant (1)
Vous pouvez utiliser le multiplicateur pour créer une disposition proportionnelle pour différents facteurs de taille.
Exemple:
Turquoise View (V1) est un carré dont la largeur est proportionnelle à la largeur de la vue avec un ratio de 1: 1,1
Gary square (V2) est une sous-vue de V1. Espace inférieur défini par la constante = 60, espace de fin défini par le multiplicateur = 1,125 et constante = 0
L'espace de fin est défini proportionnellement, l'espace inférieur défini comme constante.
Remarque: si view.attribute est égal à 0 (par exemple, espace de début), la formule de contrainte (1) sera égale à 0. Vous devez modifier le second élément de contrainte ou définir la contrainte par rapport à la marge pour afficher.attribut! = 0.
NSLayoutConstraint: Contraintes dans le code!
Lorsque nous travaillons sur une structure, si les contraintes ne sont pas trop complexes, nous ferions mieux d’utiliser Interface Builder ou NSLayoutConstraint dans le code pour le rendre plus petit, au lieu d’importer Maçonnerie ou SnapKit.
- Objectif c
// 1. create views UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; [self.view addSubview:blueView]; UIView *redView = [[UIView alloc] init]; redView.backgroundColor = [UIColor redColor]; [self.view addSubview:redView]; // 2. forbid Autoresizing blueView.translatesAutoresizingMaskIntoConstraints = NO; redView.translatesAutoresizingMaskIntoConstraints = NO; // 3. make contraints // 3.1 blueView NSLayoutConstraint *blueLeft = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1 constant:20]; [self.view addConstraint:blueLeft]; NSLayoutConstraint *blueTop = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:20]; [self.view addConstraint:blueTop]; NSLayoutConstraint *blueRight = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1 constant:-20]; [self.view addConstraint:blueRight]; NSLayoutConstraint *blueHeight = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:50]; [self.view addConstraint:blueHeight]; // 3.2 redView NSLayoutConstraint *redTop = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeBottom multiplier:1 constant:20]; [self.view addConstraint:redTop]; NSLayoutConstraint *redRight = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1 constant:-20]; [self.view addConstraint:redRight]; NSLayoutConstraint *redHeight = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeHeight multiplier:1 constant:0]; [self.view addConstraint:redHeight]; NSLayoutConstraint *redWidth = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0]; [self.view addConstraint:redWidth];