La relation entre CoreGraphics, UIViews et CALayers

J’ai toujours utilisé CoreGraphics et CoreAnimation, je comprends comment chacun d’eux travaille seul, mais pas les cas extrêmes où il faut parler avec l’autre. Je comprends aussi que les UIView sont un bon wrapper pour CALayer , où CALayer fait tout le gros du rendu, et UIView ajoute la UIView tactile.

Mais, toutes les questions que j’ai vues jusqu’à présent, attaquent le problème d’un côté ou de l’autre, et non pas l’interaction entre elles, en particulier entre CoreGraphics et CALayer .

En tout cas, ma question est …

Quelle est la relation entre CoreGraphics et CALayer?

D’après ce que je comprends, un CALayer encapsule les méthodes CoreGraphics pour le dessiner lui-même, mais il le fait une fois et peut vivre avec lui-même jusqu’à ce qu’il soit invalidé. Mais comment ces méthodes de dessin interagissent-elles avec les sous-couches de cette couche? Sont-ils exclusifs?

Par exemple, que se passe-t-il lorsque j’ai un UIView doté de sous-vues et que je surcharge la méthode drawRect ? Comment cela affecte-t-il le dessin de ses sous-couches?

Est-ce une bonne idée de mélanger les deux dans la même fonction?

En outre, je ne demande que sur iOS , je comprends que Mac est une bête différente (et aussi ces fantaisistes CIFilters , des bâtards!).

Recherches antérieures

Voici quelques questions connexes sur lesquelles j’ai déjà fait des recherches:

  1. confusion concernant quartz2d, ​​graphiques de base, animation de base, images de base . Cette question pose la question des différences entre les deux, et la réponse choisie répond bien, mais elle répond pour chaque bibliothèque individuelle comme si l’autre n’existait pas.
  2. Desserrer ou ne pas dessiner . Une autre bonne question, mais elle ne traite que du dessin de CoreGraphics et de la transmission du problème à UIKit, mais de toute façon, la réponse choisie fournit des parties du puzzle.
  3. Animation de tranches de tarte avec CALayer personnalisé . Doit être l’un des tutoriels les plus précieux que j’ai vu dans ce sujet, c’est le seul qui m’a guidé à travers le dessin d’un CALayer
  4. Ce qui est différent entre CoreGraphics et CoreAnimation Absolument déçu de la rapidité avec laquelle le demandeur a accepté la réponse, je pense qu’il y a beaucoup plus de choses à faire ici.
  5. Diverses vidéos WWDC, mais je n’en ai pas vu qui explique en détail la scope générale. Si quelqu’un répond avec une vidéo WWDC, je considère que c’est une réponse valide.

Je vais essayer de répondre à votre question à un niveau conceptuel de 20 000 pieds. Je vais essayer de rejeter mes arguments là où je suis trop généralisant, mais je vais essayer de toucher le cas commun.

La manière la plus simple d’y penser est peut-être la suivante: dans la mémoire du GPU, vous avez des textures qui, pour les besoins de cette discussion, sont des images bitmap. Un CALayer peut être associé à une texture, ou pas. Ces cas correspondraient à une couche avec une méthode -drawRect: et une couche qui existe uniquement pour contenir les sous-couches, respectivement. Conceptuellement, chaque couche qui a une texture associée à celle-ci a une texture différente (il y a des détails et des optimisations qui rendent cela pas ssortingctement / universellement vrai, mais dans le cas général et abstrait, cela peut aider à y penser) way.) Dans cette optique, la méthode -drawRect: un super- -drawRect: n’a aucun effet sur les méthodes -drawRect: et (encore une fois, dans le cas général) de la méthode -drawRect: sous-couche n’a aucun effet sur ses super-couches -drawRect: méthode. Chacun puise dans sa propre texture (également appelée “banque de sauvegarde”), puis, en fonction de l’arborescence des calques et des géomésortinges et transformations associées, le GPU regroupe toutes ces textures dans ce que vous voyez à l’écran. Lorsqu’une des couches est invalidée, directement ou indirectement (via -setNeedsDisplayInRect: , alors lorsque CA affiche la prochaine image à l’écran, les couches non valides seront redessinées en raison de leur -drawRect: appelées. Cela mettra à jour la texture associée, et une fois que toutes les textures des couches non valides seront mises à jour, le GPU les composera, générant le bitmap final que vous voyez à l’écran.

Donc, pour répondre à votre première question: Dans le cas général, non, il n’y a pas d’interaction entre les méthodes -drawRect: des CALayers distincts.

En ce qui concerne votre deuxième question: Aux fins de cette discussion, vous pouvez penser que les UIViews sont les mêmes que les CALayers. L’interrelation en ce qui concerne le dessin et les textures est largement inchangée par rapport à celle des non-UIView CALayers.

À votre troisième question: Est-ce une bonne idée de mélanger les UIViews et les CALayers? Chaque UIView a un calayer (toutes les vues dans UIKit sont sauvegardées par couche, ce qui n’est pas normalement le cas sur OSX). Donc, à un certain niveau, elles sont mélangées, que vous le vouliez ou non. Il est parfaitement judicieux d’append des sous-couches CALayer à la couche qui sous-tend un UIView, bien que cette couche n’ait pas toutes les fonctionnalités supplémentaires qu’UIView apporte à la partie. Si le but de cette couche est simplement de générer une image à afficher, alors c’est bien. Si vous souhaitez que la sous-couche / vue soit un participant de premier ordre dans la gestion tactile, ou que vous soyez positionné / dimensionné à l’aide de la fonction de mise en forme automatique, vous devrez alors utiliser une vue UIV. Il est probablement préférable de considérer un UIView comme un CALayer doté de nombreuses fonctionnalités supplémentaires. Si vous avez besoin de cette fonctionnalité, utilisez un UIView. Si vous ne le faites pas, utilisez un calayer.

En résumé: CoreGraphics est une API pour dessiner des graphiques 2D. Une utilisation courante de la CG (mais pas la seule) consiste à dessiner des images bitmap. CoreAnimation est une API fournissant un cadre organisé pour manipuler les bitmaps à l’écran. Vous pouvez utilement utiliser CoreAnimation sans jamais appeler une primitive de dessin CoreGraphics, par exemple, si toutes vos textures ont été sauvegardées par des images compilées dans votre application au moment de la construction.

J’espère que cela est utile. Laissez des commentaires si vous avez besoin de précisions, et je vais modifier pour obliger.