AUTO LAYOUT
COCOAHEADS - MONTPELLIER - 12 MAI 2016
13 MAI 2016 BACKELITEBACKELITE
SOMMAIRE
Introduction
Comprendre l’Auto Layout
Utiliser l’Auto Layout
Maîtriser l’Auto Layo...
INTRODUCTION
13 MAI 2016 BACKELITE
UTILISATION MULTI-CONTEXTE
L’interface utilisateur doit répondre dynamiquement
à 2 types de changeme...
13 MAI 2016 BACKELITE
CHANGEMENTS EXTERNES
• Utilisateur redimensionne la fenêtre de l’application (OS X)
• Utilisateur ou...
13 MAI 2016 BACKELITE
CHANGEMENTS INTERNES
• Le contenu affiché change
• Le support de l’internationalisation
• le support...
LES TROIS APPROCHES PRINCIPALES
7
Les Frames L’AutoresizingMask L’Auto Layout
13 MAI 2016 BACKELITE
LES FRAMES
Le calcul des frames : le moyen le plus flexible et le plus puissant
mais…
• ne supporte ...
13 MAI 2016 BACKELITE
L’AUTORESIZINGMASK
Simplifie la création de mise en page (layout)
Permet d’alléger l’effort de desig...
13 MAI 2016 BACKELITE
L’AUTO LAYOUT
• Supporte les changements externes et internes.
• Gère une plus large palette d’agenc...
COMPRENDRE L'AUTO LAYOUT
13 MAI 2016 BACKELITE
QU’EST CE QUE L’AUTO LAYOUT ?
L’Auto Layout
est un système d’agencement, de
mise en page, descriptif...
13 MAI 2016 BACKELITE
ANATOMIE D’UNE CONTRAINTE
13
13 MAI 2016 BACKELITE
LES ATTRIBUTS
14
13 MAI 2016 BACKELITE
LES RELATIONS
// Egalité
Blue.leading = 1.0 * Red.trailing + 8.0
// Supériorité
View.width >= 0.0 * ...
13 MAI 2016 BACKELITE
LES PRIORITÉS
• Priorité vont de 1 à 1000
• Required est 1000
• DefaultHigh est 750
• DefaultLow est...
13 MAI 2016 BACKELITE
INTRINSIC CONTENT SIZE
• La plupart des vues n’ont pas de taille préfixée
• D’autres ont une taille ...
13 MAI 2016 BACKELITE
INTRINSIC CONTENT SIZE
18
Vue Intrinsic Content Size
UIView -
UISlider Largeur
UILabels, UIButton, U...
13 MAI 2016 BACKELITE
INTRINSIC CONTENT SIZE
• intrinsicContentSize() est mieux que sizeToFit()
• Appeler invalidateIntrin...
13 MAI 2016 BACKELITE
INTRINSIC CONTENT SIZE
• L’intrinsicContentSize génère deux contraintes par dimensions
20
13 MAI 2016 BACKELITE
INTRINSIC CONTENT SIZE
• L’intrinsicContentSize génère deux contraintes par dimensions
21
view.heigh...
13 MAI 2016 BACKELITE
INTRINSIC CONTENT SIZE
• L’intrinsicContentSize génère deux contraintes par dimensions
22
view.heigh...
13 MAI 2016 BACKELITE
INTRINSIC CONTENT SIZE
• L’intrinsicContentSize génère deux contraintes par dimensions
23
view.heigh...
13 MAI 2016 BACKELITE
INTRINSIC CONTENT SIZE
• L’intrinsicContentSize génère deux contraintes par dimensions
24
view.heigh...
13 MAI 2016 BACKELITE
CONTENT HUGGING & CONTENT COMPRESSION
25
13 MAI 2016 BACKELITE
CONTENT HUGGING & CONTENT COMPRESSION
• Il est possible de modifier leur priorités
26
func setConten...
13 MAI 2016 BACKELITE
LE PROCESSUS D’AGENCEMENT
27
Vues
Contraintes
Priorités
intrinsic
ContentSize
Moteur
d’agencement
(l...
13 MAI 2016 BACKELITE
LE PROCESSUS D’AGENCEMENT
28
Constraints
change
Update
Pass
Layout
Pass
Display
Application
Run Loop
13 MAI 2016 BACKELITE
LE PROCESSUS D’AGENCEMENT
Les changements d’une contrainte
• activation / désactivation
• changement...
13 MAI 2016 BACKELITE
LE PROCESSUS D’AGENCEMENT
updateConstraintes est appelé
• A chaque cycle du moteur d’agencement
• Lo...
13 MAI 2016 BACKELITE
LE PROCESSUS D’AGENCEMENT
La phase de Layout
Traverse la hiérarchie de vue de haut en bas
• Appel à ...
13 MAI 2016 BACKELITE
LES PROBLÈMES QUE L’ON PEUT RENCONTRER
Layout ambiguë : plusieurs agencements sont possibles
• Pas a...
UTILISER L'AUTO LAYOUT
13 MAI 2016 BACKELITE
VIA INTERFACE BUILDER
Le canvas permet :
• de créer rapidement, via un clique
droit + glisser, une c...
13 MAI 2016 BACKELITE
VIA INTERFACE BUILDER
Le panneau « Structure de
document » permet :
• de lister les contraintes
• de...
13 MAI 2016 BACKELITE
VIA INTERFACE BUILDER
L’outil d’alignement permet de
rapidement ajouter des contraintes
sur les cent...
13 MAI 2016 BACKELITE
VIA INTERFACE BUILDER
L’outils de résolutions des
problèmes d’Auto Layout permet :
• d’ajouter les c...
13 MAI 2016 BACKELITE
VIA INTERFACE BUILDER
L’inspecteur de taille permet :
• de lister toutes les contraintes
qui affecte...
13 MAI 2016 BACKELITE
VIA INTERFACE BUILDER
L’inspecteur de taille permet :
• de modifier rapidement la
constante, la rela...
13 MAI 2016 BACKELITE
VIA INTERFACE BUILDER
L’inspecteur d’attributs permet :
• de modifier la relation, la
priorité, la c...
13 MAI 2016 BACKELITE
VIA INTERFACE BUILDER
L’inspecteur d’attributs permet :
• de modifier les priorités des
content hugg...
13 MAI 2016 BACKELITE
VIA LE CODE
item1.attribute1 = multiplier x item2.attribute2 + constant
42
public convenience init(i...
13 MAI 2016 BACKELITE
VIA LE CODE
• button.centerX = superview.centerX
43
NSLayoutConstraint(item: button, attribute: .Cen...
13 MAI 2016 BACKELITE
VIA LE CODE
• button.centerX = superview.centerX
44
NSLayoutConstraint(item: button, attribute: .Cen...
13 MAI 2016 BACKELITE
VIA LE CODE
• button.centerX = superview.centerX
45
NSLayoutConstraint(item: button, attribute: .Cen...
13 MAI 2016 BACKELITE
VIA LE CODE
• button.centerX = superview.centerX
46
NSLayoutConstraint(item: button, attribute: .Cen...
13 MAI 2016 BACKELITE
VIA LE CODE
• button.centerX = 1.0 x superview.centerX
47
NSLayoutConstraint(item: button, attribute...
13 MAI 2016 BACKELITE
VIA LE CODE
• button.centerX = superview.centerX
48
NSLayoutConstraint(item: button, attribute: .Cen...
13 MAI 2016 BACKELITE
VIA LE CODE
• button.centerX = superview.centerX
49
NSLayoutConstraint(item: button, attribute: .Cen...
13 MAI 2016 BACKELITE
VIA LE CODE
• button.centerX = superview.centerX + 0.0
50
NSLayoutConstraint(item: button, attribute...
13 MAI 2016 BACKELITE
• button.bottom = superview.bottom - <padding>
NSLayoutConstraint(item: button, attribute: .Bottom,
...
13 MAI 2016 BACKELITE
NSLAYOUTANCHOR
• Simplifie la création de contrainte
• Facilite la lisibilité
52
b.topAnchor.constra...
13 MAI 2016 BACKELITE
NSLAYOUTANCHOR
• Empêche la création de contrainte invalide
53
v1.leadingAnchor.constraintEqualToCon...
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
• Simplifie la création de contraintes
• Facilite la lisibilité
• Suppo...
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
55
cancelButton acceptButton
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
56
[cancelButton]-[acceptButton]
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
57
NSLayoutConstraint.constraintsWithVisualFormat(
"[cancelButton]-[acc...
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
58
NSLayoutConstraint.constraintsWithVisualFormat(
"[cancelButton]-[acc...
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
59
[cancelButton]-[acceptButton]
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
60
[cancelButton ]— -[acceptButton ]
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
61
[cancelButton(72)]—12-[acceptButton(50)]
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
62
[cancelButton(72 )]—12-[acceptButton(50)]
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
63
[cancelButton(72@250)]—12-[acceptButton(50)]
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
64
[cancelButton(72@250)]—12-[acceptButton(50)]
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
65
[cancelButton(72@250)]—12-[acceptButton( 50)]
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
66
[cancelButton(72@250)]—12-[acceptButton(>=50)]
13 MAI 2016 BACKELITE
NSLayoutConstraint.constraintsWithVisualFormat(
"[cancelButton(72@250)]—12-[acceptButton(>=50)]",
op...
13 MAI 2016 BACKELITE
NSLayoutConstraint.constraintsWithVisualFormat(
"[cancelButton(72@250)]—( )-[acceptButton(>=50)]",
o...
13 MAI 2016 BACKELITE
NSLayoutConstraint.constraintsWithVisualFormat(
"[cancelButton(72@250)]—(spacing)-[acceptButton(>=50...
13 MAI 2016 BACKELITE
NSLayoutConstraint.constraintsWithVisualFormat(
"[cancelButton(72@ )]—(spacing)-[acceptButton(>=50)]...
13 MAI 2016 BACKELITE
NSLayoutConstraint.constraintsWithVisualFormat(
"[cancelButton(72@p)]—(spacing)-[acceptButton(>=50)]...
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
72
[cancelButton]-[acceptButton]
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
73
[cancelButton]-[acceptButton ]
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
74
[cancelButton]-[acceptButton(==cancelButton)]
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
75
|[cancelButton]-[acceptButton(==cancelButton)]|
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
76
| [cancelButton]-[acceptButton(==cancelButton)] |
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
77
|-[cancelButton]-[acceptButton(==cancelButton)]-|
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
78
|- -[cancelButton]-[acceptButton(==cancelButton)]- -|
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
79
|-5-[cancelButton]-[acceptButton(==cancelButton)]-5-|
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
80
H:|-5-[cancelButton]-[acceptButton(==cancelButton)]-5-|
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
81
H:|-5-[cancelButton]-[acceptButton(==cancelButton)]-5-|
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
82
NSLayoutConstraint.constraintsWithVisualFormat(
"H:|-5-[cancelButton...
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
83
NSLayoutConstraint.constraintsWithVisualFormat(
"H:|-5-[cancelButton...
13 MAI 2016 BACKELITE
LE LANGUAGE DU FORMAT VISUEL
84
NSLayoutConstraint.constraintsWithVisualFormat(
"V:|-5-[cancelButton...
13 MAI 2016 BACKELITE
AJOUT DE CONTRAINTES
• Méthodes sur UIView
85
// ajout
public func addConstraint(constraint: NSLayou...
13 MAI 2016 BACKELITE
AJOUT DE CONTRAINTES
translatesAutoresizingMaskIntoConstraints
• convertit les frames en contraintes...
13 MAI 2016 BACKELITE
AJOUT DE CONTRAINTES
87
Sur quelle vue ajouter les
contraintes ?
13 MAI 2016 BACKELITE
AJOUT DE CONTRAINTES
88
Sur quelle vue ajouter les
contraintes ?
13 MAI 2016 BACKELITE
AJOUT DE CONTRAINTES
89
Sur quelle vue ajouter les
contraintes ?
13 MAI 2016 BACKELITE
AJOUT DE CONTRAINTES
90
Sur quelle vue ajouter les
contraintes ?
13 MAI 2016 BACKELITE
AJOUT DE CONTRAINTES
91
Sur quelle vue ajouter les
contraintes ?
13 MAI 2016 BACKELITE
AJOUT DE CONTRAINTES
92
Sur quelle vue ajouter les
contraintes ?
13 MAI 2016 BACKELITE
AJOUT DE CONTRAINTES
93
Sur quelle vue ajouter les
contraintes ?
13 MAI 2016 BACKELITE
AJOUT DE CONTRAINTES
94
Sur quelle vue ajouter les
contraintes ?
13 MAI 2016 BACKELITE
ACTIVATION / DÉSACTIVATION DE CONTRAINTES
• Méthodes sur NSLayoutConstraint
95
// activation - désac...
13 MAI 2016 BACKELITE
AUTO LAYOUT ET LES LABELS
UILabel multi-ligne :
• Mettre le nombre de ligne à 0
• preferredMaxLayout...
13 MAI 2016 BACKELITE
AUTO LAYOUT ET SCROLLVIEW
• Défini la contentSize de la scrollView
• L’ensemble des contraintes doit...
13 MAI 2016 BACKELITE
AUTO LAYOUT ET SCROLLVIEW
98
UIScrollview
ContentView
View View
View
View
13 MAI 2016 BACKELITE
ANIMATION
// Ensures that all pending layout operations have been
completed
containerView.layoutIfNe...
MAÎTRISER L'AUTO LAYOUT
13 MAI 2016 BACKELITE
COMPRENDRE LES LOGS DE LA CONSOLE
Unable to simultaneously satisfy constraints.
Probably at least on...
13 MAI 2016 BACKELITE
COMPRENDRE LES LOGS DE LA CONSOLE
Unable to simultaneously satisfy constraints.
Probably at least on...
13 MAI 2016 BACKELITE
COMPRENDRE LES LOGS DE LA CONSOLE
Unable to simultaneously satisfy constraints.
Probably at least on...
13 MAI 2016 BACKELITE
COMPRENDRE LES LOGS DE LA CONSOLE
Unable to simultaneously satisfy constraints.
Probably at least on...
13 MAI 2016 BACKELITE
COMPRENDRE LES LOGS DE LA CONSOLE
Unable to simultaneously satisfy constraints.
Probably at least on...
13 MAI 2016 BACKELITE
COMPRENDRE LES LOGS DE LA CONSOLE
Ajout d’identifiants sur les contraintes
Ajout d’identifiants d’ac...
13 MAI 2016 BACKELITE
DETECTION DES LAYOUTS AMBIGUS
• hasAmbigousLayout
retourne vrai si la vue a sa frame mal placé
• exe...
13 MAI 2016 BACKELITE
RÉSOUDRE LES LAYOUTS AMBIGUS
• Ajout de contraintes supplémentaires
• Mais ce n’est pas toujours le ...
13 MAI 2016 BACKELITE
DÉSACTIVER LE SCROLL VERTICAL D’UNE SCROLLVIEW
109
UIScrollview
ContentView
View View
View
View
0
0
...
13 MAI 2016 BACKELITE
DÉSACTIVER LE SCROLL HORIZONTAL D’UNE SCROLLVIEW
110
UIScrollview
ContentView
View View
View
View
0 ...
13 MAI 2016 BACKELITE
VUE FLOTTANTE DANS UNE SCROLLVIEW
111
UIScrollview Container
UIScrollview
ContentView
View View
View...
13 MAI 2016 BACKELITE
LE SPLIT VIEW
112
Split View
Master View Detail View
00
0 0
0
0
0
= 1/3 = x 3
13 MAI 2016 BACKELITE
LE SPLIT VIEW
113
Split View
Master View Detail View
0
0
0
0
0
= 1/3 = x 3
13 MAI 2016 BACKELITE
RÉPARTITION DE VUES DE MÊME TAILLE SUR UN AXE
114
Superview
Vue 1 Vue 2 Vue 3 Vue 4
= =
=
=
= =
13 MAI 2016 BACKELITE
RÉPARTITION DE VUES DE MÊME TAILLE SUR UN AXE
115
Superview
=
Vue 1 Vue 2 Vue 3 Vue 4
= =
= =
=
13 MAI 2016 BACKELITE
RÉPARTITION DE VUES AVEC ESPACEMENT DE MÊME TAILLE SUR UN AXE
116
Superview
Vue 1 Vue 2 Vue 3
= =
=
...
13 MAI 2016 BACKELITE
CENTRER UN GROUPE DE VUES
117
Superview
Conteneur
Vue
Vue
Vue
Vue
0
0
0
0
13 MAI 2016 BACKELITE
UILAYOUTGUIDE
• Définie un rectangle qui peut interagir avec le moteur d’agencement.
• Remplace les ...
13 MAI 2016 BACKELITE
UILAYOUTGUIDE
• Définie un rectangle qui peut interagir avec le moteur d’agencement.
• Remplace les ...
13 MAI 2016 BACKELITE
TOP/BOTTOM LAYOUT GUIDE
• Représente le bord du haut et du bas de la surface visible du viewControll...
13 MAI 2016 BACKELITE
LAYOUT MARGINS GUIDE
• Représente les marges de la vue
• Utilise les valeurs le la propriété layoutM...
13 MAI 2016 BACKELITE
READABLE CONTENT GUIDE
• Définie la largeur maximal pour le texte
• Dépends de la taille du type dyn...
13 MAI 2016 BACKELITE
SEMANTIC CONTENT ATTRIBUTES
• Détermine lorsque si la vue doit basculer lors d’un changement du sens...
BONNES PRATIQUES
13 MAI 2016 BACKELITE
BONNES PRATIQUES
• Ne plus utiliser les frames, bounds ou center pour changer les dimensions et
la p...
13 MAI 2016 BACKELITE
BONNES PRATIQUES
• Utiliser les topLayoutGuide et BottomLayoutGuide lorsque la vue s’étend
sous les ...
13 MAI 2016 BACKELITE
BONNES PRATIQUES
• Utiliser les priorités pour résoudre votre layout
• Garder en tête la localisatio...
13 MAI 2016 BACKELITE
QUELQUES LIENS
128
Références
Auto Layout Guide https://developer.apple.com/library/ios/documentatio...
mickael.laloum@backelite.com
www.backelite.com
CONTACTEZ-NOUS
13 MAI 2016 BACKELITE 129
Mickael Laloum
iOS Lead Developer
Prochain SlideShare
Chargement dans…5
×

Meetup CocoaHeads Montpellier : conférence sur l'Auto Layout

1 198 vues

Publié le

Découvrez, en quelques slides, le résumé de la conférence sur l'Auto Layout du dernier CocoaHeads Montpellier qui a eu lieu le 12 mai 2016 !

Publié dans : Technologie
0 commentaire
0 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Aucun téléchargement
Vues
Nombre de vues
1 198
Sur SlideShare
0
Issues des intégrations
0
Intégrations
5
Actions
Partages
0
Téléchargements
2
Commentaires
0
J’aime
0
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Meetup CocoaHeads Montpellier : conférence sur l'Auto Layout

  1. 1. AUTO LAYOUT COCOAHEADS - MONTPELLIER - 12 MAI 2016
  2. 2. 13 MAI 2016 BACKELITEBACKELITE SOMMAIRE Introduction Comprendre l’Auto Layout Utiliser l’Auto Layout Maîtriser l’Auto Layout Bonnes pratiques 2
  3. 3. INTRODUCTION
  4. 4. 13 MAI 2016 BACKELITE UTILISATION MULTI-CONTEXTE L’interface utilisateur doit répondre dynamiquement à 2 types de changements : • changements externes • changements internes 4
  5. 5. 13 MAI 2016 BACKELITE CHANGEMENTS EXTERNES • Utilisateur redimensionne la fenêtre de l’application (OS X) • Utilisateur ouvre / ferme le Split View sur un iPad • La rotation de l’appareil • L’apparition / disparition de la barre de status en mode (enregistrement, appel en cours…) • Le support de différentes catégories de tailles d’écran (size classes) • Le support de différentes tailles d’écran 5
  6. 6. 13 MAI 2016 BACKELITE CHANGEMENTS INTERNES • Le contenu affiché change • Le support de l’internationalisation • le support des types dynamiques 6
  7. 7. LES TROIS APPROCHES PRINCIPALES 7 Les Frames L’AutoresizingMask L’Auto Layout
  8. 8. 13 MAI 2016 BACKELITE LES FRAMES Le calcul des frames : le moyen le plus flexible et le plus puissant mais… • ne supporte que les changements externes • requiert un effort considérable pour designer, à débogguer et à maintenir • l’effort augmente d'autant plus que l'interface doit être dynamique. 8
  9. 9. 13 MAI 2016 BACKELITE L’AUTORESIZINGMASK Simplifie la création de mise en page (layout) Permet d’alléger l’effort de design mais… • Ne convient que pour des agencements simples. • Ne supporte que les changements externes. 9
  10. 10. 13 MAI 2016 BACKELITE L’AUTO LAYOUT • Supporte les changements externes et internes. • Gère une plus large palette d’agencement. • Allége l’effort de design, de déboggage et de maintenance même pour les mises en page complexe. 10
  11. 11. COMPRENDRE L'AUTO LAYOUT
  12. 12. 13 MAI 2016 BACKELITE QU’EST CE QUE L’AUTO LAYOUT ? L’Auto Layout est un système d’agencement, de mise en page, descriptif basé sur des contraintes 12 Calcule dynamiquement la taille ainsi que les dimensions de toutes les vues de la hiérarchie en fonction de contraintes placées sur ces vues.
  13. 13. 13 MAI 2016 BACKELITE ANATOMIE D’UNE CONTRAINTE 13
  14. 14. 13 MAI 2016 BACKELITE LES ATTRIBUTS 14
  15. 15. 13 MAI 2016 BACKELITE LES RELATIONS // 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 15
  16. 16. 13 MAI 2016 BACKELITE LES PRIORITÉS • Priorité vont de 1 à 1000 • Required est 1000 • DefaultHigh est 750 • DefaultLow est 250 • Les priorités les plus fortes l’emporte 16
  17. 17. 13 MAI 2016 BACKELITE INTRINSIC CONTENT SIZE • La plupart des vues n’ont pas de taille préfixée • D’autres ont une taille prédéfinie • sizeToFit • sizeThatFits: • Avec l’Auto Layout, cette taille se nomme l’intrinsicContentSize 17
  18. 18. 13 MAI 2016 BACKELITE INTRINSIC CONTENT SIZE 18 Vue Intrinsic Content Size UIView - UISlider Largeur UILabels, UIButton, UISwitch, UITextfield Hauteur et largeur UITextView, UIImageView Peut varié
  19. 19. 13 MAI 2016 BACKELITE INTRINSIC CONTENT SIZE • intrinsicContentSize() est mieux que sizeToFit() • Appeler invalidateIntrinsicContentSize() à chaque que l’intrinsicContentSize doit être recalculé 19 public func intrinsicContentSize() -> CGSize public func invalidateIntrinsicContentSize()
  20. 20. 13 MAI 2016 BACKELITE INTRINSIC CONTENT SIZE • L’intrinsicContentSize génère deux contraintes par dimensions 20
  21. 21. 13 MAI 2016 BACKELITE INTRINSIC CONTENT SIZE • L’intrinsicContentSize génère deux contraintes par dimensions 21 view.height >= 0.0 x NotAnAttribute + intrinsicContentSize.height view.height <= 0.0 x NotAnAttribute + intrinsicContentSize.height
  22. 22. 13 MAI 2016 BACKELITE INTRINSIC CONTENT SIZE • L’intrinsicContentSize génère deux contraintes par dimensions 22 view.height >= 0.0 x NotAnAttribute + intrinsicContentSize.height view.width >= 0.0 x NotAnAttribute + intrinsicContentSize.width view.height <= 0.0 x NotAnAttribute + intrinsicContentSize.height view.width <= 0.0 x NotAnAttribute + intrinsicContentSize.width
  23. 23. 13 MAI 2016 BACKELITE INTRINSIC CONTENT SIZE • L’intrinsicContentSize génère deux contraintes par dimensions 23 view.height >= 0.0 x NotAnAttribute + intrinsicContentSize.height view.width >= 0.0 x NotAnAttribute + intrinsicContentSize.width view.height <= 0.0 x NotAnAttribute + intrinsicContentSize.height view.width <= 0.0 x NotAnAttribute + intrinsicContentSize.width Content Compression Resistance
  24. 24. 13 MAI 2016 BACKELITE INTRINSIC CONTENT SIZE • L’intrinsicContentSize génère deux contraintes par dimensions 24 view.height >= 0.0 x NotAnAttribute + intrinsicContentSize.height view.width >= 0.0 x NotAnAttribute + intrinsicContentSize.width view.height <= 0.0 x NotAnAttribute + intrinsicContentSize.height view.width <= 0.0 x NotAnAttribute + intrinsicContentSize.width Content Compression Resistance Content Hugging
  25. 25. 13 MAI 2016 BACKELITE CONTENT HUGGING & CONTENT COMPRESSION 25
  26. 26. 13 MAI 2016 BACKELITE CONTENT HUGGING & CONTENT COMPRESSION • Il est possible de modifier leur priorités 26 func setContentHuggingPriority(priority: UILayoutPriority, forAxis axis: UILayoutConstraintAxis) func setContentCompressionResistancePriority(priority: UILayoutPriority, forAxis axis: UILayoutConstraintAxis)
  27. 27. 13 MAI 2016 BACKELITE LE PROCESSUS D’AGENCEMENT 27 Vues Contraintes Priorités intrinsic ContentSize Moteur d’agencement (layout engine) Mise en page (layout)
  28. 28. 13 MAI 2016 BACKELITE LE PROCESSUS D’AGENCEMENT 28 Constraints change Update Pass Layout Pass Display Application Run Loop
  29. 29. 13 MAI 2016 BACKELITE LE PROCESSUS D’AGENCEMENT Les changements d’une contrainte • activation / désactivation • changement de la constant ou de la priorité • suppression de la vue dans la hiérarchie Le moteur d’agencement recalcule la mise en page : • lorsqu’il reçoit de nouvelles valeurs • Les vues appellent superview.setNeedsLayout() 29
  30. 30. 13 MAI 2016 BACKELITE LE PROCESSUS D’AGENCEMENT updateConstraintes est appelé • A chaque cycle du moteur d’agencement • Lorsqu’on fait appel à setNeedsUpdateConstraintes() 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 30
  31. 31. 13 MAI 2016 BACKELITE LE PROCESSUS D’AGENCEMENT La phase de Layout Traverse la hiérarchie de vue de haut en bas • Appel à layoutSubviews() Positionne les frames de chaque sous-vue • Copie les frames venant du moteur d’agencement 31
  32. 32. 13 MAI 2016 BACKELITE LES PROBLÈMES QUE L’ON PEUT RENCONTRER Layout ambiguë : plusieurs agencements sont possibles • Pas assez de contraintes • Contraintes optionnels dont la priorité sont égales Layout insatisfait : aucun agencement possible • Certaines contraintes se contredisent 32
  33. 33. UTILISER L'AUTO LAYOUT
  34. 34. 13 MAI 2016 BACKELITE VIA INTERFACE BUILDER Le canvas permet : • de créer rapidement, via un clique droit + glisser, une contrainte entre deux vue. 34
  35. 35. 13 MAI 2016 BACKELITE VIA INTERFACE BUILDER Le panneau « Structure de document » permet : • de lister les contraintes • de créer via un clique droit + glisser rapidement des contraintes entre deux vues. 35
  36. 36. 13 MAI 2016 BACKELITE VIA INTERFACE BUILDER L’outil d’alignement permet de rapidement ajouter des contraintes sur les centres et les bordures 36
  37. 37. 13 MAI 2016 BACKELITE VIA INTERFACE BUILDER L’outils de résolutions des problèmes d’Auto Layout permet : • d’ajouter les contraintes manquantes • de repositionner et redimensionner les vues mal positionnées • de faire une remise à zéro des contraintes • de supprimer tous les contraintes 37
  38. 38. 13 MAI 2016 BACKELITE VIA INTERFACE BUILDER L’inspecteur de taille permet : • de lister toutes les contraintes qui affectent la vue sélectionnée. • de filtrer les contraintes suivant les classes de tailles. • de filtrer les contraintes par leur type attributs (leading, trailing…) 38
  39. 39. 13 MAI 2016 BACKELITE VIA INTERFACE BUILDER L’inspecteur de taille permet : • de modifier rapidement la constante, la relation et la priorité d’une contrainte 39
  40. 40. 13 MAI 2016 BACKELITE VIA INTERFACE BUILDER L’inspecteur d’attributs permet : • 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 40
  41. 41. 13 MAI 2016 BACKELITE VIA INTERFACE BUILDER L’inspecteur d’attributs permet : • de modifier les priorités des content hugging et content compression • de définir une largeur et une hauteur fictives pour le contenu (intrinsicContentSize) 41
  42. 42. 13 MAI 2016 BACKELITE VIA LE CODE item1.attribute1 = multiplier x item2.attribute2 + constant 42 public convenience init(item view1: AnyObject, attribute attr1: NSLayoutAttribute, relatedBy relation: NSLayoutRelation, toItem view2: AnyObject?, attribute attr2: NSLayoutAttribute, multiplier: CGFloat, constant c: CGFloat)
  43. 43. 13 MAI 2016 BACKELITE VIA LE CODE • button.centerX = superview.centerX 43 NSLayoutConstraint(item: button, attribute: .CenterX, relatedBy: .Equal, toItem: superview, attribute: .CenterX, multiplier: 1.0, constant: 0.0) item1.attribute1 = multiplier x item2.attribute2 + constant
  44. 44. 13 MAI 2016 BACKELITE VIA LE CODE • button.centerX = superview.centerX 44 NSLayoutConstraint(item: button, attribute: .CenterX, relatedBy: .Equal, toItem: superview, attribute: .CenterX, multiplier: 1.0, constant: 0.0) item1.attribute1 = multiplier x item2.attribute2 + constant
  45. 45. 13 MAI 2016 BACKELITE VIA LE CODE • button.centerX = superview.centerX 45 NSLayoutConstraint(item: button, attribute: .CenterX, relatedBy: .Equal, toItem: superview, attribute: .CenterX, multiplier: 1.0, constant: 0.0) item1.attribute1 = multiplier x item2.attribute2 + constant
  46. 46. 13 MAI 2016 BACKELITE VIA LE CODE • button.centerX = superview.centerX 46 NSLayoutConstraint(item: button, attribute: .CenterX, relatedBy: .Equal, toItem: superview, attribute: .CenterX, multiplier: 1.0, constant: 0.0) item1.attribute1 = multiplier x item2.attribute2 + constant
  47. 47. 13 MAI 2016 BACKELITE VIA LE CODE • button.centerX = 1.0 x superview.centerX 47 NSLayoutConstraint(item: button, attribute: .CenterX, relatedBy: .Equal, toItem: superview, attribute: .CenterX, multiplier: 1.0, constant: 0.0) item1.attribute1 = multiplier x item2.attribute2 + constant
  48. 48. 13 MAI 2016 BACKELITE VIA LE CODE • button.centerX = superview.centerX 48 NSLayoutConstraint(item: button, attribute: .CenterX, relatedBy: .Equal, toItem: superview, attribute: .CenterX, multiplier: 1.0, constant: 0.0) item1.attribute1 = multiplier x item2.attribute2 + constant
  49. 49. 13 MAI 2016 BACKELITE VIA LE CODE • button.centerX = superview.centerX 49 NSLayoutConstraint(item: button, attribute: .CenterX, relatedBy: .Equal, toItem: superview, attribute: .CenterX, multiplier: 1.0, constant: 0.0) item1.attribute1 = multiplier x item2.attribute2 + constant
  50. 50. 13 MAI 2016 BACKELITE VIA LE CODE • button.centerX = superview.centerX + 0.0 50 NSLayoutConstraint(item: button, attribute: .CenterX, relatedBy: .Equal, toItem: superview, attribute: .CenterX, multiplier: 1.0, constant: 0.0) item1.attribute1 = multiplier x item2.attribute2 + constant
  51. 51. 13 MAI 2016 BACKELITE • button.bottom = superview.bottom - <padding> NSLayoutConstraint(item: button, attribute: .Bottom, relatedBy: .Equal, toItem: superview, attribute: .Bottom, multiplier: 1.0, constant: -padding) VIA LE CODE 51 item1.attribute1 = multiplier x item2.attribute2 + constant
  52. 52. 13 MAI 2016 BACKELITE NSLAYOUTANCHOR • Simplifie la création de contrainte • Facilite la lisibilité 52 b.topAnchor.constraintEqualToAnchor(view.topAnchor, constant:10) b.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, constant:10) NSLayoutConstraint(item:b, attribute: .Top, relatedBy: .Equal, toItem:view, attribute:.Top, multiplier:1, constant:10) NSLayoutConstraint(item:b, attribute:.Leading, relatedBy:.Equal, toItem:view, attribute:.Leading, multiplier:1, constant:10)
  53. 53. 13 MAI 2016 BACKELITE NSLAYOUTANCHOR • Empêche la création de contrainte invalide 53 v1.leadingAnchor.constraintEqualToConstant(100) // Error: may not respond to method v1.leadingAnchor.constraintEqualToAnchor(v2.widthAnchor) // Error: incompatible pointer type
  54. 54. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL • Simplifie la création de contraintes • Facilite la lisibilité • Supporte les relations, les priorités, les alignements 54
  55. 55. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 55 cancelButton acceptButton
  56. 56. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 56 [cancelButton]-[acceptButton]
  57. 57. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 57 NSLayoutConstraint.constraintsWithVisualFormat( "[cancelButton]-[acceptButton]", options: [], metrics: nil, views: viewsDictionary)
  58. 58. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 58 NSLayoutConstraint.constraintsWithVisualFormat( "[cancelButton]-[acceptButton]", options: [], metrics: nil, views: viewsDictionary) let cancelButton: UIButton = … let acceptButton: UIButton = … let viewsDictionary = ["cancelButton": cancelButton, "acceptButton": acceptButton]
  59. 59. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 59 [cancelButton]-[acceptButton]
  60. 60. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 60 [cancelButton ]— -[acceptButton ]
  61. 61. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 61 [cancelButton(72)]—12-[acceptButton(50)]
  62. 62. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 62 [cancelButton(72 )]—12-[acceptButton(50)]
  63. 63. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 63 [cancelButton(72@250)]—12-[acceptButton(50)]
  64. 64. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 64 [cancelButton(72@250)]—12-[acceptButton(50)]
  65. 65. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 65 [cancelButton(72@250)]—12-[acceptButton( 50)]
  66. 66. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 66 [cancelButton(72@250)]—12-[acceptButton(>=50)]
  67. 67. 13 MAI 2016 BACKELITE NSLayoutConstraint.constraintsWithVisualFormat( "[cancelButton(72@250)]—12-[acceptButton(>=50)]", options: [], metrics: nil, views: viewsDictionary) LE LANGUAGE DU FORMAT VISUEL 67
  68. 68. 13 MAI 2016 BACKELITE NSLayoutConstraint.constraintsWithVisualFormat( "[cancelButton(72@250)]—( )-[acceptButton(>=50)]", options: [], metrics: metricsDictionary, views: viewsDictionary) LE LANGUAGE DU FORMAT VISUEL 68
  69. 69. 13 MAI 2016 BACKELITE NSLayoutConstraint.constraintsWithVisualFormat( "[cancelButton(72@250)]—(spacing)-[acceptButton(>=50)]", options: [], metrics: metricsDictionary, views: viewsDictionary) LE LANGUAGE DU FORMAT VISUEL 69
  70. 70. 13 MAI 2016 BACKELITE NSLayoutConstraint.constraintsWithVisualFormat( "[cancelButton(72@ )]—(spacing)-[acceptButton(>=50)]", options: [], metrics: metricsDictionary, views: viewsDictionary) LE LANGUAGE DU FORMAT VISUEL 70
  71. 71. 13 MAI 2016 BACKELITE NSLayoutConstraint.constraintsWithVisualFormat( "[cancelButton(72@p)]—(spacing)-[acceptButton(>=50)]", options: [], metrics: metricsDictionary, views: viewsDictionary) LE LANGUAGE DU FORMAT VISUEL 71 let metricsDictionary = ["spacing": 12, "p": 250]
  72. 72. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 72 [cancelButton]-[acceptButton]
  73. 73. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 73 [cancelButton]-[acceptButton ]
  74. 74. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 74 [cancelButton]-[acceptButton(==cancelButton)]
  75. 75. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 75 |[cancelButton]-[acceptButton(==cancelButton)]|
  76. 76. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 76 | [cancelButton]-[acceptButton(==cancelButton)] |
  77. 77. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 77 |-[cancelButton]-[acceptButton(==cancelButton)]-|
  78. 78. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 78 |- -[cancelButton]-[acceptButton(==cancelButton)]- -|
  79. 79. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 79 |-5-[cancelButton]-[acceptButton(==cancelButton)]-5-|
  80. 80. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 80 H:|-5-[cancelButton]-[acceptButton(==cancelButton)]-5-|
  81. 81. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 81 H:|-5-[cancelButton]-[acceptButton(==cancelButton)]-5-|
  82. 82. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 82 NSLayoutConstraint.constraintsWithVisualFormat( "H:|-5-[cancelButton]-[acceptButton(==cancelButton)]-5-|", options: [], metrics: metricsDictionary, views: viewsDictionary)
  83. 83. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 83 NSLayoutConstraint.constraintsWithVisualFormat( "H:|-5-[cancelButton]-[acceptButton(==cancelButton)]-5-|", options: options, metrics: metricsDictionary, views: viewsDictionary) let options: NSLayoutFormatOptions = .AlignAllTop
  84. 84. 13 MAI 2016 BACKELITE LE LANGUAGE DU FORMAT VISUEL 84 NSLayoutConstraint.constraintsWithVisualFormat( "V:|-5-[cancelButton]-[acceptButton(==cancelButton)]-5-|", options: options, metrics: metricsDictionary, views: viewsDictionary) let options: NSLayoutFormatOptions = .AlignAllCenterX
  85. 85. 13 MAI 2016 BACKELITE AJOUT DE CONTRAINTES • Méthodes sur UIView 85 // ajout public func addConstraint(constraint: NSLayoutConstraint) public func addConstraints(constraints: [NSLayoutConstraint]) // suppression public func removeConstraint(constraint: NSLayoutConstraint) public func removeConstraints(constraints: [NSLayoutConstraint])
  86. 86. 13 MAI 2016 BACKELITE AJOUT DE CONTRAINTES translatesAutoresizingMaskIntoConstraints • convertit les frames en contraintes • est à true pour les contraintes créer via le code • Si on utilise les frames, le mettre à true • Sinon ne pas oublier de le mettre a false ! 86 v1.translatesAutoresizingMaskIntoConstraints = false
  87. 87. 13 MAI 2016 BACKELITE AJOUT DE CONTRAINTES 87 Sur quelle vue ajouter les contraintes ?
  88. 88. 13 MAI 2016 BACKELITE AJOUT DE CONTRAINTES 88 Sur quelle vue ajouter les contraintes ?
  89. 89. 13 MAI 2016 BACKELITE AJOUT DE CONTRAINTES 89 Sur quelle vue ajouter les contraintes ?
  90. 90. 13 MAI 2016 BACKELITE AJOUT DE CONTRAINTES 90 Sur quelle vue ajouter les contraintes ?
  91. 91. 13 MAI 2016 BACKELITE AJOUT DE CONTRAINTES 91 Sur quelle vue ajouter les contraintes ?
  92. 92. 13 MAI 2016 BACKELITE AJOUT DE CONTRAINTES 92 Sur quelle vue ajouter les contraintes ?
  93. 93. 13 MAI 2016 BACKELITE AJOUT DE CONTRAINTES 93 Sur quelle vue ajouter les contraintes ?
  94. 94. 13 MAI 2016 BACKELITE AJOUT DE CONTRAINTES 94 Sur quelle vue ajouter les contraintes ?
  95. 95. 13 MAI 2016 BACKELITE ACTIVATION / DÉSACTIVATION DE CONTRAINTES • Méthodes sur NSLayoutConstraint 95 // activation - désactivation + (void)activateConstraints:(NSArray *)constraint; + (void)deactivateConstraints:(NSArray *)constraint;
  96. 96. 13 MAI 2016 BACKELITE AUTO LAYOUT ET LES LABELS 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 96
  97. 97. 13 MAI 2016 BACKELITE AUTO LAYOUT ET SCROLLVIEW • Défini la contentSize de la scrollView • L’ensemble des contraintes doit relier les bords de la scrollview • Utilise une contentView pour facilité la création du layout • Scroll horizontal : contentView.width > scrollview.width • Scroll vertical : contentView.height > scrollview.height 97
  98. 98. 13 MAI 2016 BACKELITE AUTO LAYOUT ET SCROLLVIEW 98 UIScrollview ContentView View View View View
  99. 99. 13 MAI 2016 BACKELITE ANIMATION // Ensures that all pending layout operations have been completed containerView.layoutIfNeeded() 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() } 99
  100. 100. MAÎTRISER L'AUTO LAYOUT
  101. 101. 13 MAI 2016 BACKELITE COMPRENDRE LES LOGS DE LA CONSOLE Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. ( "<NSLayoutConstraint:0x7fff2b5b1050 H:[UIButton:0x7fff2b5ad100'Envoyer'(200)]>", "<NSLayoutConstraint:0x7fff2b5b0550 UITextField:0x7fff2b5a34a0.leading == UIView: 0x7fff2b5a3e70.leadingMargin>", "<NSLayoutConstraint:0x7fff2b5b0be0 H:[UITextField:0x7fff2b5a34a0(>=250)]>", "<NSLayoutConstraint:0x7fff2b5b0d40 H:[UITextField:0x7fff2b5a34a0]-(NSSpace(8))-[UIButton: 0x7fff2b5ad100'Envoyer']>", "<NSLayoutConstraint:0x7fff2b5b0e00 UIView:0x7fff2b5a3e70.trailingMargin == UIButton: 0x7fff2b5ad100'Envoyer'.trailing>", "<NSLayoutConstraint:0x7fff2b646d30 'UIView-Encapsulated-Layout-Width' H:[UIView: 0x7fff2b5a3e70(414)]>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7fff2b5b1050 H:[UIButton:0x7fff2b5ad100'Envoyer'(200)]> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 101
  102. 102. 13 MAI 2016 BACKELITE COMPRENDRE LES LOGS DE LA CONSOLE Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. ( "<NSLayoutConstraint:0x7fff2b5b1050 H:[UIButton:0x7fff2b5ad100'Envoyer'(200)]>", "<NSLayoutConstraint:0x7fff2b5b0550 UITextField:0x7fff2b5a34a0.leading == UIView: 0x7fff2b5a3e70.leadingMargin>", "<NSLayoutConstraint:0x7fff2b5b0be0 H:[UITextField:0x7fff2b5a34a0(>=250)]>", "<NSLayoutConstraint:0x7fff2b5b0d40 H:[UITextField:0x7fff2b5a34a0]-(NSSpace(8))-[UIButton: 0x7fff2b5ad100'Envoyer']>", "<NSLayoutConstraint:0x7fff2b5b0e00 UIView:0x7fff2b5a3e70.trailingMargin == UIButton: 0x7fff2b5ad100'Envoyer'.trailing>", "<NSLayoutConstraint:0x7fff2b646d30 'UIView-Encapsulated-Layout-Width' H:[UIView: 0x7fff2b5a3e70(414)]>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7fff2b5b1050 H:[UIButton:0x7fff2b5ad100'Envoyer'(200)]> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 102
  103. 103. 13 MAI 2016 BACKELITE COMPRENDRE LES LOGS DE LA CONSOLE Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. ( "<NSLayoutConstraint:0x7ff6da1803e0 H:[sendButton(200)] (Names: sendButton:0x7ff6da17b940 )>", "<NSLayoutConstraint:0x7ff6da17f1e0 messageTextField.leading == Superview.leadingMargin (Names: messageTextField:0x7ff6da145570, Superview:0x7ff6da173c20 )>", "<NSLayoutConstraint:0x7ff6da17fd70 H:[messageTextField(>=250)] (Names: messageTextField: 0x7ff6da145570 )>", "<NSLayoutConstraint:0x7ff6da17fed0 H:[messageTextField]-(NSSpace(8))-[sendButton] (Names: sendButton:0x7ff6da17b940, messageTextField:0x7ff6da145570 )>", "<NSLayoutConstraint:0x7ff6da180190 Superview.trailingMargin == sendButton.trailing (Names: Superview:0x7ff6da173c20, sendButton:0x7ff6da17b940 )>", "<NSLayoutConstraint:0x7ff6d8c1c780 'UIView-Encapsulated-Layout-Width' H:[Superview(414)] (Names: Superview:0x7ff6da173c20 )>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7ff6da1803e0 H:[sendButton(200)] (Names: sendButton:0x7ff6da17b940 )> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 103
  104. 104. 13 MAI 2016 BACKELITE COMPRENDRE LES LOGS DE LA CONSOLE Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. ( "<NSLayoutConstraint:0x7fbeabc50340 messageTextField.leading == Superview.leadingMargin (Names: messageTextField:0x7fbeabc31020, Superview:0x7fbeabc43ce0 )>", "<NSLayoutConstraint:0x7fbeabc509b0 H:[messageTextField(>=250)] (Names: messageTextField:0x7fbeabc31020 )>", "<NSLayoutConstraint:0x7fbeabc50b10 H:[messageTextField]-(NSSpace(8))-[sendButton] (Names: sendButton: 0x7fbeabc4ce10, messageTextField:0x7fbeabc31020 )>", "<NSLayoutConstraint:0x7fbeabc50bd0 Superview.trailingMargin == sendButton.trailing (Names: Superview: 0x7fbeabc43ce0, sendButton:0x7fbeabc4ce10 )>", "<NSLayoutConstraint:0x7fbeabc50e20 'fixedWidthLayout' H:[sendButton(200)] (Names: sendButton: 0x7fbeabc4ce10 )>", "<NSLayoutConstraint:0x7fbead92e6d0 'UIView-Encapsulated-Layout-Width' H:[Superview(414)] (Names: Superview: 0x7fbeabc43ce0 )>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7fbeabc50e20 'fixedWidthLayout' H:[sendButton(200)] (Names: sendButton:0x7fbeabc4ce10 )> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 104
  105. 105. 13 MAI 2016 BACKELITE COMPRENDRE LES LOGS DE LA CONSOLE Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSAutoresizingMaskLayoutConstraint:0x7ff2e5243430 h=--& v=--& messageTextField.midY == (Names: messageTextField:0x7ff2e522e700 )>", "<NSAutoresizingMaskLayoutConstraint:0x7ff2e52432b0 h=--& v=--& V:[messageTextField(0)] (Names: messageTextField:0x7ff2e522e700 )>", "<NSLayoutConstraint:0x7ff2e522ad40 V:[messageTextField]-(20)-| (Names: Superview:0x7ff2e522bcf0, messageTextField:0x7ff2e522e700, '|':Superview:0x7ff2e522bcf0 )>", "<NSLayoutConstraint:0x7ff2e354dc70 'UIView-Encapsulated-Layout-Height' V:[Superview(736)] (Names: Superview: 0x7ff2e522bcf0 )>", "<NSAutoresizingMaskLayoutConstraint:0x7ff2e3567470 h=-&- v=-&- 'UIView-Encapsulated-Layout-Top' V:|-(0)- [Superview] (Names: Superview:0x7ff2e522bcf0, '|':UIWindow:0x7ff2e522b7c0 )>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7ff2e522ad40 V:[messageTextField]-(20)-| (Names: Superview:0x7ff2e522bcf0, messageTextField: 0x7ff2e522e700, '|':Superview:0x7ff2e522bcf0 )> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 105
  106. 106. 13 MAI 2016 BACKELITE COMPRENDRE LES LOGS DE LA CONSOLE Ajout d’identifiants sur les contraintes Ajout d’identifiants d’accessibilité sur les vues Désactiver le translateAutoresizingMaskIntoConstraints 106 labelToTop.identifier = "labelToTop" titleLabel.accessibilityIdentifier = "titleLabel" sendButton.translatesAutoresizingMaskIntoConstraints = false
  107. 107. 13 MAI 2016 BACKELITE DETECTION DES LAYOUTS AMBIGUS • 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 107
  108. 108. 13 MAI 2016 BACKELITE RÉSOUDRE LES LAYOUTS AMBIGUS • Ajout de contraintes supplémentaires • Mais ce n’est pas toujours le cas • Modification des priorités des contraintes existantes Content Hugging, Content Compression 108
  109. 109. 13 MAI 2016 BACKELITE DÉSACTIVER LE SCROLL VERTICAL D’UNE SCROLLVIEW 109 UIScrollview ContentView View View View View 0 0 = =
  110. 110. 13 MAI 2016 BACKELITE DÉSACTIVER LE SCROLL HORIZONTAL D’UNE SCROLLVIEW 110 UIScrollview ContentView View View View View 0 0 = =
  111. 111. 13 MAI 2016 BACKELITE VUE FLOTTANTE DANS UNE SCROLLVIEW 111 UIScrollview Container UIScrollview ContentView View View View View View flottante 0 0 0 0
  112. 112. 13 MAI 2016 BACKELITE LE SPLIT VIEW 112 Split View Master View Detail View 00 0 0 0 0 0 = 1/3 = x 3
  113. 113. 13 MAI 2016 BACKELITE LE SPLIT VIEW 113 Split View Master View Detail View 0 0 0 0 0 = 1/3 = x 3
  114. 114. 13 MAI 2016 BACKELITE RÉPARTITION DE VUES DE MÊME TAILLE SUR UN AXE 114 Superview Vue 1 Vue 2 Vue 3 Vue 4 = = = = = =
  115. 115. 13 MAI 2016 BACKELITE RÉPARTITION DE VUES DE MÊME TAILLE SUR UN AXE 115 Superview = Vue 1 Vue 2 Vue 3 Vue 4 = = = = =
  116. 116. 13 MAI 2016 BACKELITE RÉPARTITION DE VUES AVEC ESPACEMENT DE MÊME TAILLE SUR UN AXE 116 Superview Vue 1 Vue 2 Vue 3 = = = = = =
  117. 117. 13 MAI 2016 BACKELITE CENTRER UN GROUPE DE VUES 117 Superview Conteneur Vue Vue Vue Vue 0 0 0 0
  118. 118. 13 MAI 2016 BACKELITE UILAYOUTGUIDE • Définie un rectangle qui peut interagir avec le moteur d’agencement. • Remplace les dummy views 118 let space1 = UILayoutGuide() view.addLayoutGuide(space1) let space2 = UILayoutGuide() view.addLayoutGuide(space2) 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
  119. 119. 13 MAI 2016 BACKELITE UILAYOUTGUIDE • Définie un rectangle qui peut interagir avec le moteur d’agencement. • Remplace les dummy views 119 let space1 = UILayoutGuide() view.addLayoutGuide(space1) let space2 = UILayoutGuide() view.addLayoutGuide(space2) NSLayoutConstraint.constraintsWithVisualFormat( "H:[saveButton][space1][cancelButton][space2(==space1)][clearButton]", options: .AlignAllBaseline, metrics: nil, views: views)
  120. 120. 13 MAI 2016 BACKELITE TOP/BOTTOM LAYOUT GUIDE • Représente le bord du haut et du bas de la surface visible du viewController courant • En dessous de la statusBar ou navigationBar • Au dessus de tabBar 120
  121. 121. 13 MAI 2016 BACKELITE LAYOUT MARGINS GUIDE • Représente les marges de la vue • Utilise les valeurs le la propriété layoutMargins • Marges de 8 points par défaut sur chaque bord • Les marges de la vue racine d’un contrôleur ne sont pas modifiable 121
  122. 122. 13 MAI 2016 BACKELITE READABLE CONTENT GUIDE • Définie la largeur maximal pour le texte • Dépends de la taille du type dynamique • Reste toujours entre les margins 122
  123. 123. 13 MAI 2016 BACKELITE SEMANTIC CONTENT ATTRIBUTES • Détermine lorsque si la vue doit basculer lors d’un changement du sens de la lecture • Les position Leading et trailing s’inversent • Alors que Top, Bottom, Left et Right ne bouge pas 123
  124. 124. BONNES PRATIQUES
  125. 125. 13 MAI 2016 BACKELITE BONNES PRATIQUES • 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 125
  126. 126. 13 MAI 2016 BACKELITE BONNES PRATIQUES • Utiliser les topLayoutGuide et BottomLayoutGuide lorsque la vue s’étend sous les bars • Evitez d’overrider le layoutSubviews() • Ne pensez plus frames mais relations • Activer / Désactiver les contraintes au lieu de les ajouter / retirer • Utiliser les baselines au lieu de top/bottom • Déterminer la taille d’un composant via ses contraintes • Override intrinsicContentSize judicieusement 126
  127. 127. 13 MAI 2016 BACKELITE BONNES PRATIQUES • Utiliser les priorités pour résoudre votre layout • Garder en tête la localisation • Overrider updateContraints judicieusement • Ne jamais désactiver toutes les contraintes : self.view.constraints 127
  128. 128. 13 MAI 2016 BACKELITE QUELQUES LIENS 128 Références Auto Layout Guide https://developer.apple.com/library/ios/documentation/UserExperience/ Conceptual/AutolayoutPG/index.html#//apple_ref/doc/uid/TP40010853-CH7- SW1 Adopting Auto Layout https://developer.apple.com/library/watchos/documentation/UserExperience/ Conceptual/AutolayoutPG/AutoLayoutbyExample/AutoLayoutbyExample.html#// apple_ref/doc/uid/TP40010853-CH5-SW7 Mysteries of Auto Layout, Part 1 https://developer.apple.com/videos/play/wwdc2015/218/ Mysteries of Auto Layout, Part 2 https://developer.apple.com/videos/play/wwdc2015/219/
  129. 129. mickael.laloum@backelite.com www.backelite.com CONTACTEZ-NOUS 13 MAI 2016 BACKELITE 129 Mickael Laloum iOS Lead Developer

×