Een inleiding tot Quartz 2D

Wat is Quartz 2D?

Quartz 2D is de 2D-tekenmachine van Apple, een belangrijk onderdeel van het Core Graphics-framework. U kunt vaak Quartz 2D zien, aangeduid als Core Graphics of gewoon CG.

Quartz 2D maakt gebruik van het "schildersmodel". In het schildersmodel past elke opeenvolgende tekenbewerking een laag "verf" toe op een uitvoer "canvas", vaak een pagina genoemd. Zie het als een kunstenaar die aan een schilderij werkt. Als de kunstenaar het hele canvas blauw zou beschilderen en vervolgens wat wolken op het doek zou schilderen, dan zouden de wolken het blauw eronder bedekken. Zodra iets op het canvas is "geverfd", kan het niet worden gewijzigd, maar door er meer verf bovenop toe te voegen.

Alle tekeningen in Quartz 2D worden gedaan via een grafische context van het type CGContextRef. Met een verwijzing naar een grafische context kunt u de Quartz 2D-functies gebruiken om naar de context te tekenen, bewerkingen uit te voeren, zoals de context vertalen en de grafische statusparameters wijzigen, zoals lijndikte en vulkleur. Quartz 2D is een op C gebaseerde API. Als zodanig zal u de C-functies aanroepen die in de context als een parameter worden doorgegeven.

Als u naar het scherm op iOS wilt gaan, moet u a UIView en negeer het drawRect (_ :)methode. Het zit hierbinnen drawRect (_ :) methode die u elke aangepaste tekening gaat doen. Je zou moeten nooit bel de drawRect (_ :) methode rechtstreeks in uw code. Als u het scherm moet bijwerken met nieuwe tekenopdrachten, moet u de methoden bellen setNeedsDisplay () of setNeedsDisplayInRect (_ :).

Bij gebruik van Quartz 2D op iOS, de coördinaat (0,0) bevindt zich links bovenaan het scherm. De x-coördinaat neemt toe als je naar rechts gaat en de y-coördinaat neemt toe naarmate je naar beneden gaat.

Gedurende deze tutorial, kunt u de Quartz 2D programmeergids raadplegen. Het doel van deze tutorial is om aan de slag te gaan met Quartz 2D. Er is veel dat niet zal worden gedekt en om volledig te waarderen wat Quartz 2D te bieden heeft. Ik stel voor dat je de programmeergids leest.

Laten we aan de slag met Quartz 2D, met deze korte introductie uit de weg.

1. Voorbereiden van een UIView voor tekenen

Ervan uitgaande dat je een project open hebt staan ​​en klaar bent om te gaan werken met Quartz 2D, zijn de stappen die je moet nemen vrij eenvoudig. U moet een klasse maken die een subklasse is van UIView, Voeg een ... toe uitzicht van de Objectbibliotheek naar uw project in Interface Builder en stel de klasse van die weergave in op de UIView subklasse die u hebt gemaakt. Laten we dit stap voor stap doornemen.

Stap 1: Subclassering UIView

Ga naar het dossier > nieuwe > Het dossier… . Onder de iOS sectie, selecteer Bron en kies dan Cocoa Touch Class als de sjabloon.

Geef op het volgende scherm je klas een naam, zorg ervoor dat het een is UIView subklasse en stel de taal in Snel. druk op volgende en kies waar je je nieuwe les wilt opslaan.

Als u de bron van uw nieuw gemaakte klasse bekijkt, ziet u de drawRect (_ :) methode. Het is momenteel becommentarieerd, maar we zullen dat in enkele ogenblikken veranderen.

import UIKit-klasse DrawLineView: UIView / * // Alleen negeren drawRect: als u een aangepaste tekening uitvoert. // Een lege implementatie beïnvloedt de prestaties tijdens de animatie nadelig. override func drawRect (rect: CGRect) // Tekeningcode * /

Stap 2: Een weergave toevoegen en de klas instellen

Open het storyboard van het project en open het Objectbibliotheek aan de rechterkant. Voer in het zoekveld onderaan "UIView"om objecten uit te filteren waarin we niet geïnteresseerd zijn.

Sleep een UIView bijvoorbeeld op de view controller. Met de geselecteerde weergave opent u de Identiteitsinspecteur aan de rechterkant en verandering Klasse naar wat je de subklasse hebt genoemd.

Elke code die u toevoegt in de drawRect (_ :) methode zal worden getekend wanneer de UIView subklasse wordt geïnstantieerd. De weergave configureert automatisch de tekenomgeving, zodat u onmiddellijk kunt beginnen met tekenen. Het beeld configureert de CGContextRef vermeld aan het begin van deze les en het is binnen de drawRect (_ :) methode waar u een verwijzing naar zult krijgen.

2. Startersproject

Om ons snel van start te laten gaan, heb ik een startersproject voorzien dat alle weergaven al bedraad en klaar voor gebruik heeft. De UIView subklassen zijn genoemd naar de tekenopdracht die we gaan verkennen. Als we bijvoorbeeld leren over het tekenen van lijnen, krijgt de bijbehorende klasse een naam DrawLinesView.

Je kunt het startersproject downloaden van GitHub. We beginnen met het coderen in de volgende stap.

3. Verkrijgen van een verwijzing naar de grafische context

Voordat u een tekening kunt maken, moet u een verwijzing naar de grafische context krijgen. Dit wordt als volgt bereikt.

laat context = UIGraphicsGetCurrentContext ()

Dit levert een ondoorzichtig type op, CGContextRef, en je gaat dit voorbij context in de C-functies om de aangepaste tekening te maken. Nu we weten hoe we een referentie naar de grafische context kunnen krijgen, kunnen we beginnen met het verkennen van de tekenopdrachten.

4. Een lijn tekenen

Als u het startersproject hebt gedownload, opent u DrawLineView.swift en voeg het volgende toe aan de drawRect (_ :) methode.

override func drawRect (rect: CGRect) let context = UIGraphicsGetCurrentContext () CGContextSetStrokeColorWithColor (context, UIColor.redColor (). CGColor) CGContextMoveToPoint (context, 0, 0) CGContextAddLineToPoint (context, 200, 200) CGContextStrokePath (context)

We krijgen eerst een verwijzing naar de tekencontext zoals eerder besproken. Omdat dit iets is dat we voor elk voorbeeld doen, zal ik dit in de komende voorbeelden niet noemen.

De CGContextSetStrokeColorWithColor (_: _ :) functie stelt de kleur in waarmee de lijn wordt getekend of gestreept. De parameters die we doorgeven zijn de grafische context en de nieuwe lijnkleur.

Als je de grafische context ziet als het canvas van een schilder, dan is de CGContextMoveToPoint (_: _: _ :) functie verplaatst het penseel naar een bepaald punt op het canvas waarvan het moet beginnen of gaat door met tekenen. Stel je voor dat je op een stuk papier tekent, je hand optilt en naar een ander deel van het papier gaat en blijft tekenen. In wezen is dat wat deze methode tot stand brengt. We geven de grafische context en een x- en y-coördinaat door om de tekening te starten.

De CGContextAddLineToPoint (_: _: _ :) functie neemt als parameters de grafische context, de x-waarde voor het einde van het lijnsegment en de y-waarde voor het einde van het lijnsegment. Nadat u het lijnsegment hebt toegevoegd, wordt het huidige punt ingesteld op het eindpunt van het lijnsegment. We startten de tekenbewerking bij (0,0), na deze tekenbewerking staat de cursor of het penseel op (200.200).

Tot slot, om de daadwerkelijke tekening te doen moet u de CGContextStrokePath (_ :) functie doorgeven in de grafische context. Deze functie tekent gewoon een lijn langs het pad dat we hebben opgegeven.

Bouw het voorbeeldproject en voer het uit om het effect te zien.

5. Een rechthoek tekenen

Open DrawRectangleView.swift en voeg het volgende toe aan de drawRect (_ :) methode. Je zou nu al vertrouwd moeten zijn met de eerste twee regels.

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 (context, rechthoek) CGContextStrokePath (context)

De CGRectMake (_: _: _: _ :) functie is onderdeel van CGGeometry en biedt een eenvoudige manier om een CGRect structuur. Zoals de naam al aangeeft, CGRect  is een structuur die de locatie en afmetingen van een rechthoek bevat. EEN CGRect heeft twee velden, oorsprong en grootte, welk gebied CGPoint en een CGSize respectievelijk. Als u niet bekend bent met deze gegevenstypen, moet u snel lezen in de CGGeometry-referentie.

We creëren een constante, rechthoek, de ... gebruiken CGRectMake (_: _: _: _ :) functie en bel de CGContextAddRect (_: _ :) functie, die als parameters de grafische context en a CGRect. Ten slotte bellen we CGContextStrokePath (context) om de rechthoek te tekenen.

Bouw en voer het project uit om de rechthoek te zien die op het scherm is getekend.

6. Een cirkel tekenen

Open DrawCircleView.swift en werk het drawRect (_ :) methode als volgt.

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 (context, rechthoek) CGContextStrokePath (context) 

Je vraagt ​​je misschien af ​​waarom we bellen CGRectMake (_: _: _: _ :) wanneer we een cirkel tekenen? De rechthoek is het gebied waarin de cirkel moet passen. In de bovenstaande code maken we een cirkel met behulp van een vierkant. Als u een ovaal of ellips wilt tekenen, moet u de rechthoek meer rechthoekig van vorm maken.

We noemen dan de CGContextAddEllipseInRect (_: _ :) functie, die als parameters de grafische context en de rechthoek neemt waarin de ellips wordt getekend. De cirkel wordt getekend door te roepen CGContextStrokePath (_ :), doorgeven in de grafische context.

7. Een boog tekenen

Open DrawArcView.swift en voeg de volgende code toe binnen de drawRect (_ :) methode.

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

De CGContextAddArc (_: _: _: _: _: _: _ :) functie vergt nogal wat parameters:

  • de grafische context
  • de x-waarde voor het midden van de boog
  • de y-waarde voor het midden van de boog
  • de straal van de boog
  • de hoek tot het startpunt van de boog, gemeten in radialen vanaf de positieve x-as
  • de hoek tot het eindpunt van de boog, gemeten in radialen vanaf de positieve x-as
  • een waarde van 1 om een ​​boog met de wijzers van de klok mee of een waarde van te maken 0 om een ​​boog tegen de klok in te maken

8. Een pad tekenen

Als u complexere vormen wilt tekenen, maakt u een pad en lijnt u het af. Bekijk de drawRect (_ :) methode in DrawPathView.swift.

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

In de drawRect (_ :) methode, we bellen CGContextAddLineToPoint (_: _: _ :) een aantal keren om een ​​driehoek te maken. Merk op dat de driehoek niet gevuld is, alleen gestreept. In de volgende stap zullen we zien hoe de driehoek gevuld kan worden met kleur.

9. Een pad vullen

Open FillPathView.swift en werk het drawRect (_ :) methode zoals hieronder getoond.

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

In de vorige stap hebben we een pad gestreken, maar je kunt ook een pad vullen met een bepaalde kleur. In bovenstaande drawRect (_ :) methode, beginnen we met het maken van een pad voor dezelfde driehoek als in het vorige voorbeeld. Deze keer stellen we een vulkleur in met behulp van de CGContextSetFillColorWithColor (_: _ :) functie en oproep CGContextFillPath (_ :) liever dan CGContextStrokePath (_ :).

10. Een Ellips vullen

Behalve het vullen van paden, kunt u ook ellipsen en rechthoeken vullen. In dit voorbeeld vullen we een ovaal in. Het vullen van een rechthoek lijkt echter veel op elkaar. Documentatie zal u vertellen hoe dat is gebeurd. Werk het drawRect (_ :) methode in FillEllipseView.swift zoals hieronder getoond.

override func drawRect (rect: CGRect) let context = UIGraphicsGetCurrentContext () CGContextSetLineWidth (context, 8.0) CGContextSetStrokeColorWithColor (context, UIColor.redColor (). CGColor) laat rectangle = CGRectMake (50,50, frame.size.width-100, frame.size.height-100) CGContextAddEllipseInRect (context, rechthoek) CGContextStrokePath (context) CGContextSetFillColorWithColor (context, UIColor.greenColor (). CGColor) CGContextFillEllipseInRect (context, rechthoek) 

Het grootste deel van deze code zou nu bekend moeten zijn. We gebruiken een nieuwe functie, CGContextSetLineWidth (_: _ :), om de lijndikte in te stellen en we bellen CGContextFillEllipseInRect (_: _ :) om de ellips te vullen. Deze functie neemt als parameters de grafische context en de rechthoek waarin de ellips moet worden opgevuld.

11. Lijnen toevoegen

De CGContextAddLines (_: _: _ :) functie is een handige functie wanneer u een aantal verbonden rechte lijnsegmenten hebt die u wilt tekenen. Hier herscheppen we de driehoek van eerder in de voorbeelden, met behulp van de CGContextAddLines (_: _: _ :) functie. Voeg de volgende code toe aan AddLinesView.swift.

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

De CGContextAddLines (_: _: _ :) functie neemt als parameters de grafische context, een reeks waarden die het begin- en eindpunt specificeren van de lijnsegmenten om te tekenen als CGPoint structuren en het aantal elementen in de array. Merk op dat het eerste punt in de array het beginpunt aangeeft.

12. Een verloop tekenen

Met Quartz 2D is het eenvoudig om hellingen te tekenen. Zowel lineaire als radiale verlopen worden ondersteund. In dit voorbeeld tekenen we een lineaire gradiënt. De documentatie helpt u als u geïnteresseerd bent in het tekenen van radiale verlopen. Voeg het volgende toe aan DrawGradientView.swift.

 override func drawRect (rect: CGRect) let context = UIGraphicsGetCurrentContext () laat colorspace = CGColorSpaceCreateDeviceRGB () laat kleuren = [UIColor.redColor (). CGColor, UIColor.blueColor (). CGColor] laten locaties: [CGFloat] = [0.0 , 0,5] laat verloop = CGGradientCreateWithColors (kleurenruimte, kleuren, locaties) laat startPoint = CGPointMake (0,0) laat endPoint = CGPointMake (200.200) CGContextDrawLinearGradient (context, verloop, startpunt, eindpunt, 0) 

De CGContextDrawLinearGradient (_: _: _: _: _ :) functie neemt als parameters:

  • de grafische context
  • een CGGradient structuur
  • een startpunt
  • een eindpunt
  • optievlaggen die aangeven of de vulling wordt verlengd tot voorbij het start- of eindpunt

EEN CGGradient structuur definieert een vloeiende overgang tussen kleuren in een gebied. Het heeft een kleurenruimte, twee of meer kleuren en een locatie voor elke kleur. De constanten kleur ruimte, kleuren, en locaties in het bovenstaande voorbeeld vertegenwoordigen deze onderdelen waaruit het CGGradient.

Om het verloop te tekenen, noemen we het CGContextDrawLinearGradient (_: _: _: _: _ :) functie, doorgeven in de grafische context, de CGGradient, begin- en eindwaarden, en 0 om aan te geven dat de vulling verder moet gaan dan de startlocatie.

13. Een schaduw tekenen

Een schaduw is een afbeelding die wordt getekend onderaan, en verschoven ten opzichte van, een grafisch object zodat de schaduw het effect van een lichtbron op het grafische object nabootst. - Quartz 2D programmeergids

 Er zijn twee functies die u kunt gebruiken om schaduwen te tekenen, CGContextSetShadow (_: _: _ :) en CGContextSetShadowWithColor (_: _: _: _ :). Tijdens gebruik CGContextSetShadow (_: _: _ :), alle getekende objecten worden in de schaduw gezet met een zwarte kleur met 1/3 alfa. De CGContextSetShadowWithColor (_: _: _: _: functie stelt u in staat om een ​​kleur voor de schaduw op te geven.

Laten we kijken hoe dit in de praktijk werkt. Voeg het volgende toe aan SetShadowWithColor.swift.

override func drawRect (rect: CGRect) let context = UIGraphicsGetCurrentContext () CGContextSaveGState (context) laat shadowOffset = CGSizeMake (-15,20) CGContextSetShadowWithColor (context, shadowOffset, 3, UIColor.greenColor (). CGColor) CGContextSetStrokeColorWithColor (context, UIColor .redColor (). CGColor) laat rechthoek = CGRectMaken (50,50, frame.size.width-100, frame.size.height-100) CGContextAddRect (context, rechthoek) CGContextStrokePath (context) CGContextRestoreGState (context) 

Wanneer u schaduwen tekent, moet u de status van de grafische context opslaan, eventuele vereiste wijzigingen aanbrengen en vervolgens de grafische staat herstellen. Wij bellen CGContextSaveGState (_ :) om de huidige status van de grafische context op te slaan, geeft u een offset op voor de schaduw, shadowOffset, en bel de CGContextSetShadowWithColor (_: _: _: _ :) functie. Deze functie neemt als parameters:

  • de grafische context
  • de offset voor de schaduw
  • de hoeveelheid vervaging
  • de kleur van de schaduw

De rest van de code moet u bekend voorkomen. Ten slotte herstellen we de grafische context door te bellen CGContextRestoreGState (_ :), doorgeven in de grafische context.

14. Een blij gezicht tekenen

Ik dacht dat het leuk zou zijn om deze tutorial te beëindigen door een eenvoudig blij gezicht te tekenen met wat we tijdens deze tutorial hebben geleerd. Voeg het volgende toe aan DrawHappyFaceView.swift.

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

De implementatie van de drawRect (_ :) De methode zou nu zinvol moeten zijn en je zou een blij gezicht naar het scherm moeten trekken.

Conclusie

Hiermee komt deze tutorial tot een einde. U moet nu een basiskennis hebben van hoe u aangepaste tekeningen kunt maken met behulp van de Quartz 2D-tekenmachine. Ik hoop dat je iets nuttigs hebt geleerd door deze tutorial te lezen.