Académique Documents
Professionnel Documents
Culture Documents
Introduction
Comprendre l’Auto Layout
Utiliser l’Auto Layout
Maîtriser l’Auto Layout
Bonnes pratiques
• changements externes
• changements internes
7
LES FRAMES
mais…
mais…
L’Auto Layout
// Egalité
Blue.leading = 1.0 * Red.trailing + 8.0
// Supériorité
View.width >= 0.0 * NotAnAttribute + 40.0
// Infériorité
View.width <= 0.0 * NotAnAttribute + 280.0
UIView -
UISlider Largeur
UILabels, UIButton, UISwitch,
Hauteur et largeur
UITextfield
UITextView, UIImageView Peut varié
Content Hugging
view.height <= 0.0 x NotAnAttribute + intrinsicContentSize.height
view.width <= 0.0 x NotAnAttribute + intrinsicContentSize.width
Vues
Contraintes
Moteur Mise
d’agencement en page
(layout engine) (layout)
Priorités
intrinsic
ContentSize
Constraints
change
Application Update
Run Loop Pass
Layout
Display
Pass
Overrider lorsque :
• Les changements des contraintes est trop lents
• Une vue fait régulièrement des changements sur ses contraintes
• Appel du super à la fin de la méthode
La phase de Layout
Le canvas permet :
Le panneau « Structure de
document » permet :
• de modifier rapidement la
constante, la relation et la
priorité d’une contrainte
• de modifier la relation, la
priorité, la constante, le
multiplier de la contrainte
• d’intervertir le premier et le
deuxième élément
• de marquer la contrainte comme
fictive
• button.centerX = superview.centerX
• button.centerX = superview.centerX
• button.centerX = superview.centerX
• button.centerX = superview.centerX
• button.centerX = superview.centerX
• button.centerX = superview.centerX
b.topAnchor.constraintEqualToAnchor(view.topAnchor, constant:10)
b.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, constant:10)
v1.leadingAnchor.constraintEqualToConstant(100)
// Error: may not respond to method
v1.leadingAnchor.constraintEqualToAnchor(v2.widthAnchor)
// Error: incompatible pointer type
cancelButton acceptButton
[cancelButton]-[acceptButton]
NSLayoutConstraint.constraintsWithVisualFormat(
"[cancelButton]-[acceptButton]",
options: [], metrics: nil, views: viewsDictionary)
NSLayoutConstraint.constraintsWithVisualFormat(
"[cancelButton]-[acceptButton]",
options: [], metrics: nil, views: viewsDictionary)
[cancelButton]-[acceptButton]
[cancelButton ]— -[acceptButton ]
[cancelButton(72)]—12-[acceptButton(50)]
[cancelButton(72 )]—12-[acceptButton(50)]
[cancelButton(72@250)]—12-[acceptButton(50)]
[cancelButton(72@250)]—12-[acceptButton(50)]
[cancelButton(72@250)]—12-[acceptButton( 50)]
[cancelButton(72@250)]—12-[acceptButton(>=50)]
NSLayoutConstraint.constraintsWithVisualFormat(
"[cancelButton(72@250)]—12-[acceptButton(>=50)]",
options: [], metrics: nil, views: viewsDictionary)
NSLayoutConstraint.constraintsWithVisualFormat(
"[cancelButton(72@250)]—( )-[acceptButton(>=50)]",
options: [], metrics: metricsDictionary, views: viewsDictionary)
NSLayoutConstraint.constraintsWithVisualFormat(
"[cancelButton(72@250)]—(spacing)-[acceptButton(>=50)]",
options: [], metrics: metricsDictionary, views: viewsDictionary)
NSLayoutConstraint.constraintsWithVisualFormat(
"[cancelButton(72@ )]—(spacing)-[acceptButton(>=50)]",
options: [], metrics: metricsDictionary, views: viewsDictionary)
NSLayoutConstraint.constraintsWithVisualFormat(
"[cancelButton(72@p)]—(spacing)-[acceptButton(>=50)]",
options: [], metrics: metricsDictionary, views: viewsDictionary)
[cancelButton]-[acceptButton]
[cancelButton]-[acceptButton ]
[cancelButton]-[acceptButton(==cancelButton)]
|[cancelButton]-[acceptButton(==cancelButton)]|
| [cancelButton]-[acceptButton(==cancelButton)] |
|-[cancelButton]-[acceptButton(==cancelButton)]-|
|- -[cancelButton]-[acceptButton(==cancelButton)]- -|
|-5-[cancelButton]-[acceptButton(==cancelButton)]-5-|
H:|-5-[cancelButton]-[acceptButton(==cancelButton)]-5-|
H:|-5-[cancelButton]-[acceptButton(==cancelButton)]-5-|
NSLayoutConstraint.constraintsWithVisualFormat(
"H:|-5-[cancelButton]-[acceptButton(==cancelButton)]-5-|",
options: [], metrics: metricsDictionary, views: viewsDictionary)
NSLayoutConstraint.constraintsWithVisualFormat(
"H:|-5-[cancelButton]-[acceptButton(==cancelButton)]-5-|",
options: options, metrics: metricsDictionary, views: viewsDictionary)
NSLayoutConstraint.constraintsWithVisualFormat(
"V:|-5-[cancelButton]-[acceptButton(==cancelButton)]-5-|",
options: options, metrics: metricsDictionary, views: viewsDictionary)
// ajout
public func addConstraint(constraint: NSLayoutConstraint)
public func addConstraints(constraints: [NSLayoutConstraint])
// suppression
public func removeConstraint(constraint: NSLayoutConstraint)
public func removeConstraints(constraints: [NSLayoutConstraint])
translatesAutoresizingMaskIntoConstraints
• convertit les frames en contraintes
• est à true pour les contraintes créer via le code
v1.translatesAutoresizingMaskIntoConstraints = false
// activation - désactivation
+ (void)activateConstraints:(NSArray *)constraint;
+ (void)deactivateConstraints:(NSArray *)constraint;
UILabel multi-ligne :
• Mettre le nombre de ligne à 0
• preferredMaxLayoutWidth indique la largeur pour le retour à la ligne
• Ajuster les priorités de content hugging et content compression
< iOS 8 :
• preferredMaxLayoutWidth != frame
• doit mettre la jour preferredMaxLayoutWidth à la main
UIScrollview
ContentView
View View
View
View
UIView.animateWithDuration(1.0) {
// Make all constraint changes here
myConstraint.constant = 0.0
// Forces the layout of the subtree animation block
// and then captures all of the frame changes
containerView.layoutIfNeeded()
}
labelToTop.identifier = "labelToTop"
titleLabel.accessibilityIdentifier = "titleLabel"
Désactiver le translateAutoresizingMaskIntoConstraints
sendButton.translatesAutoresizingMaskIntoConstraints = false
• hasAmbigousLayout
retourne vrai si la vue a sa frame mal placé
• exerciceAmbiguityInLayout
commute entre les différentes possibilité de layout
• constraintAffectingLayoutForAxis
return la liste des contraintes associés à un axe
• _autolayoutTrace
affiche un diagnostique sur la hiérarchie de vue entière
UIScrollview 0
ContentView
View View =
=
View
View
UIScrollview
ContentView
View View
0 0
View
View
=
=
UIScrollview Container 0
UIScrollview
ContentView
0
View View
View
0
View
View
flottante
Split View 0 0
0
0 0
= 1/3 =x3
0 0
Split View 0
0
0 0
= 1/3 =x3
Superview
= = = =
=
=
Superview
= = = =
= =
Superview
= = = =
=
=
Superview
Conteneur 0
Vue
Vue 0
Vue
0 Vue
space1.widthAnchor.constraintEqualToAnchor(space2.widthAnchor).active = true
saveButton.trailingAnchor.constraintEqualToAnchor(space1.leadingAnchor).active = true
cancelButton.leadingAnchor.constraintEqualToAnchor(space1.trailingAnchor).active = true
cancelButton.trailingAnchor.constraintEqualToAnchor(space2.leadingAnchor).active = true
clearButton.leadingAnchor.constraintEqualToAnchor(space2.trailingAnchor).active = true
NSLayoutConstraint.constraintsWithVisualFormat(
"H:[saveButton][space1][cancelButton][space2(==space1)][clearButton]",
options: .AlignAllBaseline, metrics: nil, views: views)
• Ne plus utiliser les frames, bounds ou center pour changer les dimensions et
la position de la vue
• Éviter de donner un largeur et longueur fixe à une vue
• Donner des noms qui ont du sens à vos vues
• Toujours utiliser Leading et Trailing
• translateAutoresizingMaskIntoConstraints = NO
• Utiliser les layoutMarginsGuides
• Utiliser les readableContentGuides pour les textes
Références
mickael.laloum@backelite.com
www.backelite.com