2010-09-24 12 views
15

Je ne trouve pas de réponse décente pour m'expliquer la différence entre ces 2 fonctions. quand est-ce que tout le monde est appelé, et comment est-ce que l'un est différent de l'autre? Par exemple, est-ce que je ne peux pas simplement mettre en page mes vues à l'intérieur de DrawRect?drawrect Vs layoutsubviews - NSView - Cocoa touch

Merci

Répondre

56

-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).
+0

Bonne réponse. Merci! – Idan

-2

Peut-être que je n'ai pas toutes les réponses, mais je peux vous dire que: - layoutSubviews est appelée lorsque le cadre de la vue change - drawRect est appelée lorsque setNeedDisplay est appelé

La plupart du temps, vous n'utiliserez pas layoutSubviews.

Il peut y avoir d'autres cas, mais il pourrait vous donner un premier morceau de réponse ^^

Bonne chance

+0

Veuillez donner plus de détails autour de votre affirmation que "la plupart du temps vous n'utiliserez pas layoutSubviews". –