Une introduction à Quartz 2D

Qu'est-ce que le quartz 2D?

Quartz 2D est le moteur de dessin 2D d’Apple, un composant important du framework Core Graphics. Vous pouvez souvent voir Quartz 2D appelé Core Graphics ou simplement CG..

Quartz 2D utilise le "modèle du peintre". Dans le modèle du peintre, chaque opération de dessin successive applique une couche de «peinture» à un «canevas» de sortie, souvent appelé page. Pensez à cela comme à un artiste travaillant sur une peinture. Si l'artiste peignait toute la toile en bleu, puis quelques nuages ​​sur la toile, les nuages ​​recouvriraient le bleu en dessous. Une fois que quelque chose est "peint" sur la toile, il ne peut pas être changé, mais en ajoutant plus de peinture dessus.

Tout le dessin en Quartz 2D se fait à travers un contexte graphique de type CGContextRef. Avec une référence à un contexte graphique, vous pouvez utiliser les fonctions Quartz 2D pour dessiner le contexte, effectuer des opérations telles que la traduction du contexte et modifier les paramètres d'état graphique, tels que la largeur de trait et la couleur de remplissage. Quartz 2D est une API basée sur C, en tant que telle, vous invoquerez les fonctions C qui passent dans le contexte en tant que paramètre..

Pour dessiner à l’écran sur iOS, vous devez sous-classer un UIView et remplacer sa drawRect (_ :)méthode. C'est à l'intérieur drawRect (_ :) méthode que vous ferez un dessin personnalisé. Vous devriez jamais appeler le drawRect (_ :) méthode directement dans votre code. Si vous devez mettre à jour l’écran avec de nouvelles commandes de dessin, vous devez appeler les méthodes. setNeedsDisplay () ou setNeedsDisplayInRect (_ :).

Lorsque vous utilisez Quartz 2D sur iOS, les coordonnées (0,0) est en haut à gauche de l'écran. La coordonnée x augmente lorsque vous vous déplacez à droite et la coordonnée y augmente lorsque vous vous déplacez.

Tout au long de ce tutoriel, vous souhaiterez peut-être consulter le guide de programmation Quartz 2D. Ce didacticiel a pour objectif de vous familiariser avec Quartz 2D. Il y a beaucoup de choses qui ne seront pas couvertes et pour apprécier pleinement tout ce que Quartz 2D a à offrir, je vous suggère de lire le guide de programmation..

Avec cette brève introduction, commençons à utiliser Quartz 2D.

1. Préparer un UIView pour le dessin

En supposant que vous ayez un projet ouvert et que vous êtes prêt à commencer à travailler avec Quartz 2D, les étapes à suivre sont assez simples. Vous devrez créer une classe qui est une sous-classe de UIView, ajouter un vue depuis la bibliothèque d’objets vers votre projet dans Interface Builder, et définissez la classe de cette vue sur le UIView sous-classe que vous avez créée. Passons en revue cette étape par étape.

Étape 1: Sous-classement UIView

Aller à Fichier > Nouveau > Fichier… . Sous le iOS section, sélectionnez La source et ensuite choisir Cacao Touch Class comme modèle.

Sur l’écran qui suit, donnez un nom à votre classe, assurez-vous que c’est un UIView sous-classe et définir la langue sur Rapide. presse Suivant et choisissez où sauvegarder votre nouvelle classe.

Si vous affichez la source de votre classe nouvellement créée, vous verrez le drawRect (_ :) méthode. Il est actuellement commenté, mais nous allons changer cela dans quelques instants.

import UIKit class DrawLineView: UIView / * // Ne substitue que drawRect: si vous effectuez un dessin personnalisé. // Une implémentation vide affecte négativement les performances lors de l'animation. redéfinit func drawRect (rect: CGRect) // code de dessin * /

Étape 2: Ajout d'une vue et définition de la classe

Ouvrez le story-board du projet et ouvrez le Bibliothèque d'objets sur la droite. Dans le champ de recherche en bas, entrez "UIView"filtrer les objets qui ne nous intéressent pas.

Faites glisser un UIView exemple sur le contrôleur de vue. Avec la vue sélectionnée, ouvrez le Inspecteur d'identité à droite et change Classe à tout ce que vous avez nommé la sous-classe.

Tout code que vous ajoutez à l'intérieur du drawRect (_ :) la méthode sera tirée lorsque le UIView la sous-classe est instanciée. La vue configure automatiquement l'environnement de dessin afin que vous puissiez commencer à dessiner immédiatement. La vue configure le CGContextRef mentionné au début de cette leçon et il se trouve à l'intérieur du drawRect (_ :) méthode que vous obtiendrez une référence à ce sujet.

2. Projet de démarrage

Pour nous permettre de démarrer rapidement, j'ai fourni un projet de démarrage qui a toutes les vues déjà câblées et prêtes à être utilisées. le UIView les sous-classes sont nommées d'après la commande de dessin que nous allons explorer. Par exemple, quand on apprend à dessiner des lignes, la classe correspondante sera nommée DrawLinesView.

Vous pouvez télécharger le projet de démarrage depuis GitHub. Nous allons commencer à coder à l'étape suivante.

3. Obtenir une référence au contexte graphique

Avant de pouvoir réaliser un dessin, vous devez obtenir une référence au contexte graphique. Ceci est accompli comme suit.

laissez context = UIGraphicsGetCurrentContext ()

Cela retourne un type opaque, CGContextRef, et vous passerez ceci le contexte dans les fonctions C pour faire le dessin personnalisé. Maintenant que nous savons comment obtenir une référence au contexte graphique, nous pouvons commencer à explorer les commandes de dessin..

4. Tracer une ligne

Si vous avez téléchargé le projet de démarrage, ouvrez DrawLineView.swift et ajoutez ce qui suit au drawRect (_ :) méthode.

override func drawRect (rect: CGRect) let context = UIGraphicsGetCurrentContext () CGContextSetStrokeColorWithColor (context, UIColor.redColor (). CGColor) CGContextMoveToPoint (context, 0, 0) CGContextAddLineToPoint (contexte, défense)

Nous obtenons d’abord une référence au contexte de dessin, comme indiqué précédemment. Parce que c’est quelque chose que nous ferons pour chaque exemple, je ne le mentionnerai pas dans les exemples à venir..

le CGContextSetStrokeColorWithColor (_: _ :) fonction définit la couleur avec laquelle la ligne sera dessinée ou tracée. Les paramètres que nous transmettons sont le contexte graphique et la nouvelle couleur de trait..

Si vous considérez le contexte graphique comme la toile d’un peintre, le CGContextMoveToPoint (_: _: _ :) function déplace le pinceau sur un point particulier de la toile à partir duquel commencer ou continuer à dessiner. Imaginez dessiner sur un morceau de papier, lever la main, passer à une autre partie du papier et continuer à dessiner. C'est essentiellement ce que cette méthode accomplit. Nous passons dans le contexte graphique et une coordonnée x et y pour commencer le dessin de.

le CGContextAddLineToPoint (_: _: _ :) function prend comme paramètres le contexte graphique, la valeur x pour la fin du segment de ligne et la valeur y pour la fin du segment. Après avoir ajouté le segment de ligne, le point actuel sera défini sur l'extrémité du segment de ligne. Nous avons commencé l'opération de dessin à (0,0). Après cette opération de dessin, le curseur ou le pinceau est à (200,200)..

Enfin, pour faire le dessin, vous devez appeler le CGContextStrokePath (_ :) fonction passant dans le contexte graphique. Cette fonction trace simplement une ligne le long du chemin que nous avons spécifié.

Générez et exécutez l'exemple de projet pour voir l'effet.

5. Dessiner un rectangle

Ouvrir DrawRectangleView.swift et ajoutez ce qui suit au drawRect (_ :) méthode. Vous devriez maintenant être familiarisé avec les deux premières lignes.

override func drawRect (rect: CGRect) let context = UIGraphicsGetCurrentContext () CGContextSetStrokeColorWithColor (context, UIColor.redColor (). CGColor) let rectangle = CGRectMake (50,50, frame.size.width-100, frame.size.height- 100) CGContextAddRect (contexte, rectangle) CGContextStrokePath (contexte)

le CGRectMake (_: _: _: _ :) fonction fait partie de CGGeometry et fournit un moyen facile de créer un CGRect structure. Comme son nom l'indique, CGRect  est une structure qui contient l'emplacement et les dimensions d'un rectangle. UNE CGRect a deux champs, origine et Taille, quelle région CGPoint et un CGSize respectivement. Si vous n'êtes pas familier avec ces types de données, lisez-le rapidement dans la référence CGGeometry.

Nous créons une constante, rectangle, en utilisant le CGRectMake (_: _: _: _ :) fonction et appelez le CGContextAddRect (_: _ :) fonction, qui prend comme paramètres le contexte graphique et un CGRect. Enfin, nous appelons CGContextStrokePath (contexte) dessiner le rectangle.

Générez et exécutez le projet pour voir le rectangle dessiné à l'écran.

6. Tracer un cercle

Ouvrir DrawCircleView.swift et mettre à jour le drawRect (_ :) méthode comme suit.

override func drawRect (rect: CGRect) let context = UIGraphicsGetCurrentContext () CGContextSetStrokeColorWithColor (context, UIColor.redColor (). CGColor) let rectangle = CGRectMake (50,50, frame.size.width-100, frame.size.height- 100) CGContextAddEllipseInRect (contexte, rectangle) CGContextStrokePath (contexte) 

Vous vous demandez peut-être pourquoi nous appelons CGRectMake (_: _: _: _ :) quand on dessine un cercle? Le rectangle est la zone dans laquelle le cercle doit s’inscrire. Dans le code ci-dessus, nous créons un cercle en utilisant un carré. Si vous voulez dessiner un ovale ou une ellipse, vous devez créer un rectangle de forme plus rectangulaire..

Nous appelons ensuite le CGContextAddEllipseInRect (_: _ :) fonction, qui prend comme paramètres le contexte graphique et le rectangle dans lequel tracer l'ellipse. Le cercle est dessiné en appelant CGContextStrokePath (_ :), en passant dans le contexte graphique.

7. Tracer un arc

Ouvrir DrawArcView.swift et ajoutez le code suivant à l'intérieur du drawRect (_ :) méthode.

override func drawRect (rect: CGRect) let context = UIGraphicsGetCurrentContext () CGContextSetStrokeColorWithColor (context, UIColor.redColor (). CGColor) CGContextAddArc (context, 100,100,50,3.14,0,1) CGContextStrokePath (contexte) 

le CGContextAddArc (_: _: _: _: _: _: _ :) fonction prend pas mal de paramètres:

  • le contexte graphique
  • la valeur x pour le centre de l'arc
  • la valeur y pour le centre de l'arc
  • le rayon de l'arc
  • l'angle au point de départ de l'arc, mesuré en radians à partir de l'axe des x positif
  • l'angle au point final de l'arc, mesuré en radians à partir de l'axe des x positif
  • une valeur de 1 pour créer un arc dans le sens horaire ou une valeur de 0 créer un arc dans le sens antihoraire

8. Tracer un chemin

Pour dessiner des formes plus complexes, vous créez un tracé et vous le tracez. Regardez le drawRect (_ :) méthode en DrawPathView.swift.

override func drawRect (rect: CGRect) let context = UIGraphicsGetCurrentContext () CGContextSetStrokeColorWithColor (context, UIColor.redColor (). CGColor) CGContextMoveToPoint (context, 25, 150) CGContextAddLineToPoint (contexte, défense, sécurité) ) CGContextAddLineToPoint (context, 25, 150) CGContextStrokePath (context) 

dans le drawRect (_ :) méthode, nous appelons CGContextAddLineToPoint (_: _: _ :) plusieurs fois pour créer un triangle. Notez que le triangle n'est pas rempli, seulement caressé. Dans la prochaine étape, nous verrons comment remplir le triangle de couleur.

9. Remplir un chemin

Ouvrir FillPathView.swift et mettre à jour le drawRect (_ :) méthode comme indiqué ci-dessous.

override func drawRect (rect: CGRect) let context = UIGraphicsGetCurrentContext () CGContextMoveToPoint (context, 25, 150) CGContextAddLineToPoint (context, 175, 150) CGContextAddLineToPoint (context, 100, 50) CGContextAdd , UIColor.redColor (). CGColor) CGContextFillPath (context)

Dans l'étape précédente, nous avons tracé un tracé, mais vous pouvez également remplir un tracé avec une couleur particulière. Au dessus drawRect (_ :) méthode, nous commençons par créer un chemin pour le même triangle que dans l'exemple précédent. Cette fois, nous définissons une couleur de remplissage à l'aide du bouton CGContextSetFillColorWithColor (_: _ :) fonction et appel CGContextFillPath (_ :) plutôt que CGContextStrokePath (_ :).

10. Remplir une ellipse

En plus de remplir des chemins, vous pouvez également remplir des ellipses et des rectangles. Dans cet exemple, nous allons remplir une ellipse. Remplir un rectangle, cependant, est très similaire. La documentation vous dira comment cela se passe. Mettre à jour le drawRect (_ :) méthode en FillEllipseView.swift comme indiqué ci-dessous.

override func drawRect (rect: CGRect) let context = UIGraphicsGetCurrentContext () CGContextSetLineWidth (contexte, 8.0) CGContextSetStrokeColorWithColor (contexte, UIColor.redColor (). CGColor) let rectangle = CGRect, plus. frame.size.height-100) CGContextAddEllipseInRect (contexte, rectangle) CGContextStrokePath (contexte) CGContextSetFillColorWithColor (contexte, UIColor.greenColor (). CGColor) CGContextFillEillipseInRect (context, rectangle) 

La plupart de ce code devrait être familier maintenant. Nous utilisons une nouvelle fonction, CGContextSetLineWidth (_: _ :), pour définir la largeur de la ligne et nous appelons CGContextFillEllipseInRect (_: _ :) remplir l'ellipse. Cette fonction prend comme paramètres le contexte graphique et le rectangle dans lequel remplir l’ellipse.

11. Ajouter des lignes

le CGContextAddLines (_: _: _ :) function est une fonction pratique lorsque vous souhaitez dessiner un nombre de segments de ligne droite connectés. Ici, nous recréons le triangle de précédemment dans les exemples, en utilisant le CGContextAddLines (_: _: _ :) une fonction. Ajoutez le code suivant à AddLinesView.swift.

override func drawRect (rect: CGRect) let context = UIGraphicsGetCurrentContext () CGContextSetStrokeColorWithColor (contexte, UIColor.redColor (). CGColor) laisse lines = [CGPointMake (25,150), CGPointMake (175,150), CGPointMake (100, 50), CGPointMake 25,150)] CGContextAddLines (contexte, lignes, 4) CGContextStrokePath (context)

le CGContextAddLines (_: _: _ :) fonction prend comme paramètres le contexte graphique, un tableau de valeurs qui spécifient les points de début et de fin des segments de ligne à dessiner CGPoint structures, et le nombre d'éléments dans le tableau. Notez que le premier point du tableau spécifie le point de départ.

12. Tracer un dégradé

Avec Quartz 2D, il est facile de dessiner des dégradés. Les gradients linéaires et radiaux sont pris en charge. Dans cet exemple, nous allons dessiner un dégradé linéaire. La documentation vous aidera si vous souhaitez dessiner des dégradés radiaux. Ajouter ce qui suit à DrawGradientView.swift.

 override func drawRect (rect: CGRect) let context = UIGraphicsGetCurrentContext () let colorpace = CGColorSpaceCreateDeviceRGB () let colors = [UIColor.redColor (). CGColor, UIColor.blueColor (). CGColor] laissez emplacements: [CGFloat] , 0.5] let gradient = CGGradientCreateWithColors (espace de couleur, couleurs, emplacements) let startPoint = CGPointMake (0,0) let endPoint = CGPointMake (200,200) CGContextDrawLinearGradient (contexte, dégradé, startPoint, endPoint, 0) 

le CGContextDrawLinearGradient (_: _: _: _: _ :) fonction prend comme paramètres:

  • le contexte graphique
  • une CGGradient structure
  • un point de départ
  • un point final
  • indicateurs d'option qui spécifient si le remplissage est étendu au-delà du point de départ ou d'arrivée

UNE CGGradient La structure définit une transition en douceur entre les couleurs d'une zone. Il possède un espace colorimétrique, deux couleurs ou plus et un emplacement pour chaque couleur. Les constantes espace de couleurs, couleurs, et Emplacements dans l'exemple ci-dessus représentent ces parties qui composent le CGGradient.

Pour dessiner le dégradé, nous appelons le CGContextDrawLinearGradient (_: _: _: _: _ :) fonction, en passant dans le contexte graphique, le CGGradient, valeurs de début et de fin, et 0 pour indiquer que le remplissage doit s'étendre au-delà du lieu de départ.

13. Dessiner une ombre

Une ombre est une image dessinée au-dessous d'un objet graphique et décalée par rapport à celui-ci, de sorte que l'ombre imite l'effet d'une source de lumière projetée sur l'objet graphique. - Guide de programmation Quartz 2D

 Il y a deux fonctions que vous pouvez utiliser pour dessiner des ombres, CGContextSetShadow (_: _: _ :) et CGContextSetShadowWithColor (_: _: _: _ :). Lors de l'utilisation CGContextSetShadow (_: _: _ :), tous les objets dessinés sont ombrés en utilisant une couleur noire avec 1/3 alpha. le CGContextSetShadowWithColor (_: _: _: _: fonction vous permet de spécifier une couleur pour l'ombre.

Voyons comment cela fonctionne dans la pratique. Ajouter ce qui suit à SetShadowWithColor.swift.

redéfinissez func drawRect (rect: CGRect) let context = UIGraphicsGetCurrentContext () .redColor (). CGColor) let rectangle = CGRectMake (50,50, frame.size.width-100, frame.size.height-100) CGContextAddRect (contexte, rectangle) CGContextStrokePath (context) CGContextRestoreGState (context) 

Lorsque vous tracez des ombres, vous devez enregistrer l'état du contexte graphique, apporter les modifications requises, puis restaurer l'état des graphiques. Nous appelons CGContextSaveGState (_ :) pour enregistrer l’état actuel du contexte graphique, spécifiez un décalage pour l’ombre, shadowOffset, et appelez le CGContextSetShadowWithColor (_: _: _: _ :) une fonction. Cette fonction prend comme paramètres:

  • le contexte graphique
  • le décalage pour l'ombre
  • la quantité de flou
  • la couleur de l'ombre

Le reste du code devrait vous être familier. Enfin, nous restaurons le contexte graphique en appelant CGContextRestoreGState (_ :), en passant dans le contexte graphique.

14. dessiner un visage heureux

J'ai pensé qu'il serait amusant de terminer ce tutoriel en dessinant un visage heureux et simple en utilisant ce que nous avons appris tout au long de ce tutoriel. Ajouter ce qui suit à DrawHappyFaceView.swift.

override func drawRect (rect: CGRect) let context = UIGraphicsGetCurrentContext () let face = CGRectMake (50,50, frame.size.width-100, frame.size.height-100) CGContextAddEllipseInRect (contexte, visage) CGContextSetFillCetFillColorWithCith (contexte, UIColor.yellowColor (). CGColor) CGContextFillEllipseInRect (contexte, visage) let leftEye = CGRectMake (75,75,10,10) CGContextSetFillColorWithColor (contexte, UIColor.blackColor (). CGColor). 115,75,10,10) CGContextFillEllipseInRect (context, rightEye) CGContextSetLineWidth (context, 3.0) CGContextAddArc (context, 100,100,30,3.14,0,1) CGContextStrokePath (context) 

La mise en œuvre de la drawRect (_ :) la méthode devrait avoir un sens maintenant et vous devriez avoir un visage heureux dessiné à l'écran.

Conclusion

Cela met fin à ce tutoriel. Vous devez maintenant avoir une compréhension de base de la réalisation de dessins personnalisés à l’aide du moteur de dessin Quartz 2D. J'espère que vous avez appris quelque chose d'utile en lisant ce tutoriel.