-layoutSubviews
est appelé à partir -layoutIfNeeded
si le drapeau « mise en page nécessaire » a été créée (en utilisant -setNeedsLayout
, ou automatiquement lorsque les limites de la vue changent). Utilisez-le pour le positionnement
votre vue
[EDIT: Utilisez-le pour le positionnement vues secondaires].
-drawRect:
est appelé à partir -displayIfNeeded
si le drapeau « affichage nécessaire » a été créée (en utilisant -setNeedsDisplay
, ou automatiquement si vous définissez view.contentMode = UIViewContentModeRedraw
).
Les deux -layoutIfNeeded
et -displayIfNeeded
sont appelés automatiquement par UIKit/CoreAnimation avant que les éléments ne soient affichés à l'écran; vous avez rarement besoin de les appeler directement.
Vous pouvez placer votre subviews dans -drawRect:
(vous pouvez même ajouter des sous-vues!), Mais cela est imprudent:
- Par défaut,
-setNeedsDisplay
n'est pas appelé automatiquement un changement de limites.
- L'implémentation de
-drawRect:
réduit les performances (UIKit/CoreAnimation doit créer pour vous un contexte graphique à base de bitmap); Ne le faites que si vous avez besoin d'effectuer un dessin personnalisé. Vous devez redessiner la vue dans -drawRect:
. Le dessin est cher. Déplacer des vues autour est bon marché.
- UIKit/CoreAnimation effectue probablement une passe de mise en page suivie d'une passe de dessin. CoreAnimation peut utiliser les informations de mise en page pour décider quelles vues doivent être dessinées (par exemple, il peut ignorer les vues masquées par les sous-vues opaques, les vues hors écran ou les sous-vues en dehors des limites d'une vue clipsToBounds = YES). grande vue). Si vous déplacez des vues pendant la phase de dessin, CoreAnimation risque de ne pas les dessiner correctement.
EDIT: Et un peu plus en détail quand je suis réveillé:
Quelle est la différence entre « affichage » et « dessiner »? L'affichage est fait par -[CALayer display]
; la mise en œuvre par défaut est (environ)
- Si répond à
-displayLayer:
, appelez le délégué de la couche [self.delegate displayLayer:self]
.-displayLayer:
est supposé mettre layer.content
à (par exemple) un CGImage,
- Dans le cas contraire, si le délégué de la couche répond à
-drawLayer:inContext:
, mis en place un contexte bitmap soutenu, appelez [self.delegate drawLayer:self inContext:context]
et enregistrer la sortie à layer.content
(la sortie est en fait un CABackingStore , qui est probablement une API privée)
- Sinon, ne modifiez pas
layer.content
.
La vue est le délégué de la couche, de sorte que vous pouvez mettre en œuvre à la place -[MyView displayLayer:]
, et faire des choses intéressantes comme
self.layer.contents = (id)([UIImage imageNamed:@"foo"].CGImage)
(qui est à peu près ce que UIImageView fait)
- A no-op, pour éviter tout "dessin". Cela peut être utile si vous avez sous-classé, par exemple, UIToolbar et que vous voulez lui donner un fond transparent. (Cela empêche également la création du CGContext/CABackingStore.)
- Déplacez les sous-vues sans la pénalité de performance (mais ce n'est toujours pas une bonne idée pour les raisons ci-dessus).
Bonne réponse. Merci! – Idan