O introducere în quartz 2D

Ce este Quartz 2D?

Quartz 2D este motorul de desen 2D al Apple, o componentă importantă a cadrului Core Graphics. Puteți vedea adesea Quartz 2D denumit Core Graphics sau pur și simplu CG.

Cuartul 2D utilizează modelul "pictorului". În modelul pictorului, fiecare operație desenată succesivă aplică un strat de "vopsea" unei "pânze" de ieșire, denumită adesea o pagină. Gândiți-vă la acest lucru ca artist care lucrează la o pictură. Dacă artistul ar picta întreaga pânză albastră și apoi va picura niște nori pe pânză, atunci norii ar acoperi albastrul de dedesubt. Odată ce ceva este "pictat" pe pânză, nu se poate schimba decât prin adăugarea mai multor vopsea deasupra ei.

Toate desenele din Quartz 2D se fac printr-un context grafic de tip CGContextRef. Cu o referință la un context grafic, puteți utiliza funcțiile Quartz 2D pentru a desena contextul, a efectua operații, cum ar fi traducerea contextului și a schimba parametrii de stare grafică, cum ar fi lățimea liniei și culoarea de umplere. Quartz 2D este un API bazat pe C, ca atare veți invoca funcțiile C care trec în context ca parametru.

Pentru a desena pe ecran în iOS, trebuie să vă subclasa a UIView și suprascrie-i drawRect (_ :)metodă. Este înăuntru drawRect (_ :) metoda pe care o veți face orice desen personalizat. Tu ar trebui nu suna drawRect (_ :) direct în codul dvs. Dacă trebuie să actualizați ecranul cu comenzi proaspete de desen, trebuie să apelați metodele setNeedsDisplay () sau setNeedsDisplayInRect (_ :).

Când folosiți Quartz 2D pe iOS, coordonatele (0,0) este în partea stângă sus a ecranului. Coordonarea x crește pe măsură ce vă deplasați la dreapta și coordonatele y cresc pe măsură ce vă deplasați în jos.

Pe parcursul acestui tutorial, vă recomandăm să consultați ghidul de programare Quartz 2D. Scopul acestui tutorial este de a începe folosind Quartz 2D. Există multe care nu vor fi acoperite și pentru a aprecia pe deplin tot ceea ce Quartz 2D are de oferit Vă sugerez să citiți ghidul de programare.

Cu această scurtă introducere din drum, să începem cu Quartz 2D.

1. Pregătirea a UIView pentru desen

Presupunând că aveți un proiect deschis și sunteți gata să începeți să lucrați cu Quartz 2D, pașii pe care trebuie să îi faceți sunt destul de simpli. Va trebui să creați o clasă care este o subclasă de UIView, adauga o vedere de la biblioteca de obiecte la proiectul tău în Interface Builder și ai seta clasa de vizualizare la UIView subclasa pe care ați creat-o. Să trecem prin acest pas cu pas.

Pasul 1: Subclasarea UIView

Mergi la Fişier > Nou > Fişier… . Sub iOS secțiune, selectați Sursă și apoi alegeți Cocoa Touch Class ca șablon.

Pe ecranul care urmează, dați clasei dvs. un nume, asigurați-vă că este a UIView subclasa și setați limba la Rapid. presa Următor → și alegeți unde să vă salvați noua clasă.

Dacă vedeți sursa clasei nou create, veți vedea drawRect (_ :) metodă. Este comentat în prezent, dar vom schimba asta în câteva momente.

importați clasa UIKit DrawLineView: UIView / * // Numai suprascrie drawRect: dacă efectuați desenul personalizat. // O implementare goală afectează în mod negativ performanța în timpul animației. suprascrie func drawRect (rect: CGRect) // Codul de desenare * /

Pasul 2: Adăugarea unei vizualizări și setarea clasei

Deschideți storyboard-ul proiectului și deschideți-l Biblioteca de obiecte pe dreapta. În câmpul de căutare din partea de jos, introduceți "UIView"pentru a filtra obiectele din care nu suntem interesați.

Trageți a UIView instanță pe controlerul de vizualizare. Cu vizualizarea selectată, deschideți Inspectorul de identitate pe dreapta și schimbare Clasă la orice ai numit subclasa.

Orice cod adăugați în interiorul drawRect (_ :) metoda va fi trasată atunci când UIView subclasa este instanțiată. Vizualizarea configurează automat mediul de desen, astfel încât să puteți începe desenul imediat. Vizualizarea configurează CGContextRef menționată la începutul acestei lecții și se află în interiorul acesteia drawRect (_ :) metodă pe care o veți face referire la aceasta.

2. Proiectul Starter

Pentru a ne face să începem rapid, am oferit un proiect demarat care are toate vizionările deja conectate și gata de utilizare. UIView subclasele sunt numite după comanda de desen pe care o vom explora. De exemplu, atunci când învățăm despre desenarea liniilor, se va numi clasa corespunzătoare DrawLinesView.

Puteți descărca proiectul starter de la GitHub. Vom începe codificarea în pasul următor.

3. Obținerea unei referințe la contextul grafic

Înainte de a putea face orice desen, trebuie să obțineți o referință la contextul grafic. Acest lucru este realizat după cum urmează.

lasă context = UIGraphicsGetCurrentContext ()

Aceasta returnează un tip opac, CGContextRef, și vei trece asta context în funcțiile C pentru a realiza desenul personalizat. Acum, când știm cum să facem referire la contextul grafic, putem începe să explorăm comenzile de desen.

4. Desenarea unei linii

Dacă ați descărcat proiectul inițial, deschideți DrawLineView.swift și adăugați următoarele la drawRect (_ :) metodă.

(context, 0, 0) CGContextAddLineToPoint (context, 200, 200) CGContextStrokePath (context) CGContextSectorColorWithColor (context, UIColor.redColor

Mai întâi se face o referire la contextul de desen, după cum se discută mai devreme. Pentru că așa ceva vom face pentru fiecare exemplu, nu voi mai menționa acest lucru în exemplele de mai jos.

CGContextSetStrokeColorWithColor (_: _ :) funcția stabilește culoarea cu care linia va fi desenată sau curbată. Parametrii pe care le transmitem sunt contextul grafic și noua culoare a stroke.

Dacă vă gândiți la contextul grafic ca pe panza unui pictor, atunci CGContextMoveToPoint (_: _: _ :) funcția deplasează pensula într-un anumit punct de pe panza din care să înceapă sau să continue desenul. Imaginați-vă că desenați pe o bucată de hârtie, ridicându-vă mâna și mutați o altă parte a hârtiei și continuând să trageți. În esență, aceasta este ceea ce realizează această metodă. Trecem în contextul grafic și o coordonată x și y pentru a începe desenul.

CGContextAddLineToPoint (_: _: _ :) funcția ia ca parametri contextul grafic, valoarea x pentru sfârșitul segmentului de linie și valoarea y pentru sfârșitul segmentului de linie. După adăugarea segmentului de linie, punctul curent va fi setat la punctul final al segmentului de linie. Am început operația de desen la (0,0), după această operație de desen cursorul sau pensula este la (200,200).

În cele din urmă, pentru a face desenul real trebuie să apelați CGContextStrokePath (_ :) funcția care trece în contextul grafic. Această funcție trage pur și simplu o linie de-a lungul căii pe care am specificat-o.

Construiți și executați proiectul de eșantion pentru a vedea efectul.

5. Desenarea unui dreptunghi

Deschis DrawRectangleView.swift și adăugați următoarele la drawRect (_ :) metodă. Ar trebui să cunoașteți primele două linii până acum.

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

CGRectMake (_: _: _: _ :) funcția face parte din CGGometria și oferă o modalitate ușoară de a crea o CGRect structura. După cum sugerează și numele, CGRect  este o structură care conține locația și dimensiunile unui dreptunghi. A CGRect are două câmpuri, origine și mărimea, care zonă CGPoint și a CGSize respectiv. Dacă nu sunteți familiarizat cu aceste tipuri de date, aveți o citire rapidă în referința CGGometrie.

Noi creăm o constantă, dreptunghi, folosind CGRectMake (_: _: _: _ :) și apelați CGContextAddRect (_: _ :) funcția, care ia ca parametri contextul grafic și a CGRect. În cele din urmă, sunăm CGContextStrokePath (context) pentru a desena dreptunghiul.

Construiți și executați proiectul pentru a vedea dreptunghiul desenat pe ecran.

6. Desenarea unui cerc

Deschis DrawCircleView.swift și actualizați drawRect (_ :) după cum urmează.

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

S-ar putea să te întrebi de ce sunăm CGRectMake (_: _: _: _ :) când desenați un cerc? Dreptunghiul este zona în care trebuie să se încadreze cercul. În codul de mai sus, creăm un cerc utilizând un pătrat. Dacă doriți să desenați o ovală sau o elipsă, atunci trebuie să faceți dreptunghiul mai dreptunghiular.

Apoi chemăm CGContextAddEllipseInRect (_: _ :) funcția, care ia ca parametri contextul grafic și dreptunghiul în care să atragă elipsa. Cercul este desenat prin apelarea CGContextStrokePath (_ :), trecând în contextul grafic.

7. Desenarea unui arc

Deschis DrawArcView.swift și adăugați următorul cod în interiorul drawRect (_ :) metodă.

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

 CGContextAddArc (_: _: _: _: _: _: _ :) funcția necesită câțiva parametri:

  • contextul grafic
  • valoarea x pentru centrul arcului
  • valoarea y pentru centrul arcului
  • raza arcului
  • unghiul față de punctul de pornire al arcului, măsurat în radiani de la axa pozitivă x
  • unghiul până la punctul final al arcului, măsurat în radiani de la axa pozitivă x
  • o valoare de 1 pentru a crea un arc în sensul acelor de ceasornic sau o valoare de 0 pentru a crea un arc în sens invers acelor de ceasornic

8. Desenarea unei căi

Pentru a desena forme mai complexe, creați o cale și îndemnați-o. Uitați-vă la drawRect (_ :) metoda în DrawPathView.swift.

override functie drawRect (rect: CGRect) permite context = UIGraphicsGetCurrentContext () CGContextSetStrokeColorWithColor (context, UIColor.redColor () .CGColor) CGContextAddLineToPoint (context, 100, 50) ) CGContextAddLineToPoint (context, 25, 150) CGContextStrokePath (context) 

În drawRect (_ :) metoda, suntem CGContextAddLineToPoint (_: _: _ :) de mai multe ori pentru a crea un triunghi. Rețineți că triunghiul nu este umplut, ci doar mângâiat. În pasul următor, vom vedea cum să umplem triunghiul cu culoarea.

9. Completarea unei căi

Deschis FillPathView.swift și actualizați drawRect (_ :) așa cum se arată mai jos.

(context, 25, 150) CGContextAddLineToPoint (context, 175, 150) CGContextAddLineToPoint (context, 100, 50) CGContextSetFillColorWithColor (context, CGContextSetFillColorWithColor) , UIColor.redColor () .CGColor) CGContextFillPath (context)

În pasul anterior, am mângâiat o cale, dar puteți completa și o cale cu o anumită culoare. În cele de mai sus drawRect (_ :) , începem prin crearea unei căi pentru același triunghi ca în exemplul anterior. De data aceasta am setat o culoare de umplere folosind CGContextSetFillColorWithColor (_: _ :) funcția și apelul CGContextFillPath (_ :) Decat CGContextStrokePath (_ :).

10. Umplerea unei elipse

În afară de căile de umplere, puteți completa elipsele și dreptunghiurile. În acest exemplu, vom completa o elipsă. Umplerea unui dreptunghi, totuși, este foarte asemănătoare. Documentația vă va spune cum sa făcut acest lucru. Actualizați drawRect (_ :) metoda în FillEllipseView.swift așa cum se arată mai jos.

override functie drawRect (rect: CGRect) permite context = UIGraphicsGetCurrentContext () CGContextSetLineWidth (context, 8.0) CGContextSetStrokeColorWithColor (context, UIColor.redColor () .CGColor) CGContextAddEllipseInRect (context, dreptunghi) CGContextStrokePath (context) CGContextSetFillColorWithColor (context, UIColor.greenColor () .CGColor) CGContextFillEllipseInRect (context, dreptunghi) 

Majoritatea acestui cod ar trebui să fie familiar până acum. Folosim o nouă funcție, CGContextSetLineWidth (_: _ :), pentru a seta lățimea liniei și apelați CGContextFillEllipseInRect (_: _ :) pentru a umple elipsa. Această funcție are ca parametri contextul grafic și dreptunghiul în care se umple elipsa.

11. Adăugarea liniilor

CGContextAddLines (_: _: _ :) funcția este o funcție utilă atunci când aveți un număr de segmente de linie dreaptă conectate pe care doriți să le desenați. Aici vom recrea triunghiul din exemplele anterioare, folosind CGContextAddLines (_: _: _ :) funcţie. Adăugați următorul cod la AddLinesView.swift.

override functie drawRect (rect: CGRect) lasa context = UIGraphicsGetCurrentContext () CGContextSetStrokeColorWithColor (context, UIColor.redColor () .CGColor) lasa linii = CGPointMake (25,150), CGPointMake 25,150)] CGContextAddLines (context, linii, 4) CGContextStrokePath (context)

CGContextAddLines (_: _: _ :) funcția ia ca parametri contextul grafic, o serie de valori care specifică punctele de început și sfârșit ale segmentelor de linie pentru a desena ca CGPoint structurile și numărul elementelor din matrice. Rețineți că primul punct din matrice specifică punctul de pornire.

12. Desenarea unui Gradient

Cu Quartz 2D, este ușor să desenați gradiente. Atât gradienții liniari cât și radiali sunt susținuți. În acest exemplu, vom desena un gradient liniar. Documentația vă va ajuta dacă sunteți interesat să desenați gradiente radiale. Adăugați următoarele la DrawGradientView.swift.

 override function drawRect (rect: CGRect) permite context = UIGraphicsGetCurrentContext () permite colorspace = CGColorSpaceCreateDeviceRGB () permite culorilor = [UIColor.redColor () CGColor, UIColor.blueColor , 0.5] permite gradient = CGGradientCreateWithColors (culori, culori, locatii) let startPoint = CGPointMake (0,0) permite endPoint = CGPointMake (200,200) CGContextDrawLinearGradient (context, gradient, startPoint, endPoint, 0) 

CGContextDrawLinearGradient (_: _: _: _: _ :) funcția are ca parametri:

  • contextul grafic
  • A CGGradient structura
  • un punct de plecare
  • un punct final
  • opțiuni care specifică dacă umplerea este extinsă dincolo de punctul de pornire sau de sfârșit

A CGGradient structura definește o tranziție lină între culorile dintr-o zonă. Are un spațiu de culoare, două sau mai multe culori și o locație pentru fiecare culoare. Constantele colorspace, colorate, și locații în exemplul de mai sus reprezintă acele părți care alcătuiesc CGGradient.

Pentru a desena gradientul, numim CGContextDrawLinearGradient (_: _: _: _: _ :) funcția, trecând în contextul grafic, CGGradient, începutul și sfârșitul valorilor și 0 pentru a indica faptul că umplutura ar trebui să se extindă dincolo de locul de plecare.

13. Desenarea unei umbre

O umbră este o imagine desenată dedesubt și un offset de la un obiect grafic astfel încât umbra să imite efectul unei surse de lumină exprimate pe obiectul grafic. - Ghid de programare 2D Quartz

 Există două funcții pe care le puteți utiliza pentru a desena umbre, CGContextSetShadow (_: _: _ :) și CGContextSetShadowWithColor (_: _: _: _ :). Atunci când se utilizează CGContextSetShadow (_: _: _ :), toate obiectele desenate sunt umbrite folosind culoarea neagră cu 1/3 alfa. CGContextSetShadowWithColor (_: _: _: _: vă permite să specificați o culoare pentru umbra.

Să vedem cum funcționează acest lucru în practică. Adăugați următoarele la SetShadowWithColor.swift.

(context, shadowOffset, 3, UIColor.greenColor () CGColor) CGContextSetStrokeColorWithColor (context, UICcolor) (context: UColorWithColor) CGContextSetStrokeColorWithColor CGContextAddRect (context, dreptunghi) CGContextStrokePath (context) CGContextRestoreGState (context) CGContextStrokePath (context) 

Când desenați umbre, ar trebui să salvați starea contextului grafic, să efectuați modificările necesare și apoi să restaurați starea grafică. Noi sunam CGContextSaveGState (_ :) pentru a salva starea actuală a contextului grafic, specificați o decalare a umbrei, shadowOffset, și apelați CGContextSetShadowWithColor (_: _: _: _ :) funcţie. Aceste funcții au ca parametri:

  • contextul grafic
  • decalajul pentru umbra
  • valoarea neclarității
  • culoarea umbrei

Restul codului trebuie să vă fie familiar. În cele din urmă, restabilim contextul grafic apelând CGContextRestoreGState (_ :), trecând în contextul grafic.

14. Desenați o față fericită

Am crezut că ar fi distractiv să închei acest tutorial, desenând o simplă față fericită folosind ceea ce am învățat pe parcursul acestui tutorial. Adăugați următoarele la DrawHappyFaceView.swift.

override funcția drawRect (rect: CGRect) permite context = UIGraphicsGetCurrentContext () permite face = CGRectMake (50,50, frame.size.width-100, frame.size.height-100) CGContextAddEllipseInRect CGContextSetFillColorWithColor (context, (CGColor) CGContextFillEllipseInRect (context, leftEye) lăsați rightEye = CGRectMake (context, leftEye) permitețiEye = CGRectMake (CGColor) 115) CGContextFillEllipseInRect (context, rightEye) CGContextSetLineWidth (context, 3.0) CGContextAddArc (context, 100,100,30,3.14,0,1) CGContextStrokePath (context) 

Punerea în aplicare a directivei drawRect (_ :) metoda ar trebui să aibă sens până acum și ar trebui să aveți o față fericită desenată pe ecran.

Concluzie

Acest lucru duce la sfârșitul acestui tutorial. Ar trebui să aveți acum o înțelegere de bază a modului de a realiza desenul personalizat folosind motorul de desenare Quartz 2D. Sper că ați învățat ceva util prin citirea acestui tutorial.

Cod