Quartz2D詳解

什么是Quartz2D?

簡(jiǎn)單來(lái)說(shuō)尘应,Quartz2D是用C語(yǔ)言封裝的二維繪圖引擎,同時(shí)支持iOS和Mac系統(tǒng),利用Quartz2D挽霉,我們可以完成以下工作:

  • 繪制圖形 : 線條\三角形\矩形\圓\弧等
  • 繪制文字
  • 繪制\生成圖片(圖像)
  • 讀取\生成PDF
  • 截圖\裁剪圖片
  • 自定義UI控件

學(xué)習(xí)Quartz2D的價(jià)值在哪里

雖然Quartz2D屬于偏底層的API翩蘸,并且UIKit已經(jīng)把我們經(jīng)常使用的控件封裝好所意,但是,面對(duì)一些自定義控件催首,復(fù)雜的控件扶踊,UIKit就顯得有些無(wú)力了。

學(xué)好Quartz2D郎任,我們就可以:

  • 繪制一些系統(tǒng)UIKit框架中不好展示的內(nèi)容秧耗,例如餅圖,環(huán)形進(jìn)度條舶治,統(tǒng)計(jì)圖表
  • 自定義一些控件
  • 不添加UI控件的情況下分井,使UI內(nèi)容更豐富
  • ……

在iOS中,我們所看見的大部分控件都是利用Quartz2D繪制出來(lái)的歼疮。

什么是圖形上下文

簡(jiǎn)單來(lái)說(shuō)杂抽,圖形上下文就相當(dāng)于一塊畫布,我們可以在這塊畫布上畫任何我們想要的內(nèi)容韩脏,最后展示在View上缩麸。

然而,這個(gè)畫布一定要在drawRect:方法里面去獲取赡矢,實(shí)現(xiàn)才有效杭朱,下面就具體講下這個(gè)方法阅仔。

drawRect:

為什么要實(shí)現(xiàn)drawRect:方法才能繪圖到view上?

因?yàn)樵赿rawRect:方法中才能取得跟view相關(guān)聯(lián)的圖形上下文

在drawRect:方法中取得上下文后弧械,就可以繪制東西到view上

drawRect如何繪圖到View上

View內(nèi)部有個(gè)layer(圖層)屬性八酒,drawRect:方法中取得的是一個(gè)Layer Graphics Context,因此刃唐,繪制的東西其實(shí)是繪制到view的layer上去了

View之所以能顯示東西羞迷,完全是因?yàn)樗鼉?nèi)部的layer

drawRect:方法如何調(diào)用的

  • 當(dāng)view第一次顯示到屏幕上時(shí),系統(tǒng)會(huì)創(chuàng)建好一個(gè)跟當(dāng)前view相關(guān)的Layer上下文
  • 系統(tǒng)會(huì)通過(guò)此上下文画饥,在drawRect:方法中繪制好當(dāng)前view的內(nèi)容
  • 主動(dòng)讓view重繪內(nèi)容的時(shí)候衔瓮,調(diào)用setNeedsDisplay或者setNeedsDisplayInRect:。我們主動(dòng)調(diào)用drawRect:方法是無(wú)效的抖甘。
  • 調(diào)用view的setNeedsDisplay或者setNeedsDisplayInRect:時(shí)
  • 注意:setNeedsDisplay和setNeedsDisplayInRect:方法調(diào)用后热鞍,屏幕并不是立即刷新,而是會(huì)在下一次刷新屏幕的時(shí)候把繪制的內(nèi)容顯示出來(lái)衔彻。

也正是系統(tǒng)會(huì)在調(diào)用這個(gè)方法之前創(chuàng)建一個(gè)與該view相關(guān)的上下文薇宠,才讓我們可以在drawRect:方法中繪制。

注意:在其他地方拿不到view相關(guān)的上下文艰额,所以不能實(shí)現(xiàn)繪制澄港。

自定義View的步驟

如何利用Quartz2D繪制東西到view上?

  1. 新建一個(gè)類悴晰,繼承自UIView
  2. 實(shí)現(xiàn)- (void)drawRect:(CGRect)rect方法慢睡,然后在這個(gè)方法中
  3. 取得跟當(dāng)前view相關(guān)聯(lián)的圖形上下文
  4. 繪制相應(yīng)的圖形內(nèi)容
  5. 利用圖形上下文將繪制的所有內(nèi)容渲染顯示到view上面

下面我就介紹如何使用Quartz2D畫各種圖形。

實(shí)現(xiàn)代碼

寫文字

NSString *text = @"我要寫的文字";
UIFont *font = [UIFont boldSystemFontOfSize:20.f];
UIColor *color = [UIColor purpleColor];
NSDictionary *attributes = @{NSForegroundColorAttributeName:color,
                             NSFontAttributeName:font};
[text drawInRect:CGRectMake(10, 20, 80, 20) withAttributes:attributes];

畫圓

CGContextRef context = UIGraphicsGetCurrentContext();  
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);//設(shè)置畫筆顏色
CGContextSetFillColorWithColor(context, [UIColor yellowColor].CGColor);//設(shè)置填充顏色
CGContextSetLineWidth(context, 5.f);//線的寬度
CGContextAddArc(context, 100, 200, 15, 0, M_PI * 2, 0);//添加一個(gè)圓
CGContextDrawPath(context, kCGPathStroke);//繪制路徑

void CGContextAddArc(CGContextRef c,CGFloat x, CGFloat y,CGFloat radius,CGFloat startAngle,CGFloat endAngle, int clockwise)

  • x,y為圓點(diǎn)坐標(biāo)
  • radius半徑
  • startAngle為開始的弧度
  • endAngle為 結(jié)束的弧度
  • clockwise 0為順時(shí)針铡溪,1為逆時(shí)針
  • ps:1弧度=180°/π (≈57.3°) 度=弧度×180°/π 360°=360×π/180 =2π 弧度

CGContextDrawPath(context, kCGPathStroke)這個(gè)方法的第二個(gè)參數(shù)是一個(gè)枚舉

  • kCGPathFill 填充非零繞數(shù)規(guī)則,
  • kCGPathEOFill 表示用奇偶規(guī)則,
  • kCGPathStroke 路徑,
  • kCGPathFillStroke 路徑填充,
  • kCGPathEOFillStroke 表示描線漂辐,不是填充

如果你只想畫一個(gè)圓而不需要填充就用kCGPathStroke,如果你不想要路徑,只想填充就用kCGPathFil棕硫,如果你既要路徑又要填充就要使用kCGPathFillStroke髓涯。

如果只是繪制路徑還可以使用這個(gè)方法

void CGContextStrokePath(CGContextRef c)

如果只是填充還可以使用這個(gè)方法

void CGContextFillPath(CGContextRef c)

畫直線

CGPoint aPoints[2];//坐標(biāo)點(diǎn)
aPoints[0] =CGPointMake(100, 80);//坐標(biāo)1
aPoints[1] =CGPointMake(130, 80);//坐標(biāo)2
CGContextAddLines(context, aPoints, 2);//添加線
CGContextDrawPath(context, kCGPathStroke); //根據(jù)坐標(biāo)繪制路徑

CGContextAddLines(CGContextRef c, const CGPoint points[],size_t count)

points[]坐標(biāo)數(shù)組,count點(diǎn)個(gè)數(shù)

如果你不需要畫折線哈扮,還有一種簡(jiǎn)單的寫法

CGContextMoveToPoint(context, 100, 80); //移動(dòng)到坐標(biāo)1
CGContextAddLineToPoint(context, 130, 80);//從坐標(biāo)一畫線到坐標(biāo)2

畫矩形

CGRect rect1 = CGRectMake(100, 120, 20, 20);//創(chuàng)建一個(gè)rect
CGContextAddRect(context, rect1);//添加一個(gè)矩形
CGContextStrokePath(context);//繪制路徑
//如果要填充要使用另外一個(gè)方法CGContextFillPath(context);

對(duì)于矩形纬纪,我們可以使用一下兩個(gè)簡(jiǎn)便方法繪制

繪制空心矩形(不填充)

void CGContextStrokeRect(CGContextRef __nullable c, CGRect rect)

繪制實(shí)心矩形(填充)

void CGContextFillRect(CGContextRef __nullable c, CGRect rect)

畫扇形

畫扇形,也就畫圓滑肉,只不過(guò)是設(shè)置角度的大小包各,形成一個(gè)扇形。

下面代碼以10為半徑圍繞圓心畫指定角度扇形靶庙。

CGContextMoveToPoint(context, 160, 180);//移到起始點(diǎn)问畅,即扇形的圓心
CGContextAddArc(context, 160, 180, 30,  -60 * M_PI / 180, -120 * M_PI / 180, 1);//添加扇形
CGContextClosePath(context);//閉合路徑(畫扇形一定要有起始點(diǎn)和終點(diǎn),且要閉合)
CGContextDrawPath(context, kCGPathFillStroke); //繪制路徑

畫橢圓

CGContextAddEllipseInRect(context, CGRectMake(160, 180, 20, 8)); //橢圓  
CGContextDrawPath(context, kCGPathFillStroke); 

畫三角形

畫三角形只要三個(gè)點(diǎn)就行跟畫一條線方式一樣,把三點(diǎn)連接起來(lái)

CGPoint sPoints[3];//坐標(biāo)點(diǎn)  
sPoints[0] =CGPointMake(100, 220);//坐標(biāo)1  
sPoints[1] =CGPointMake(130, 220);//坐標(biāo)2  
sPoints[2] =CGPointMake(130, 160);//坐標(biāo)3  
CGContextAddLines(context, sPoints, 3);//添加線  
CGContextClosePath(context);//封起來(lái)  
CGContextDrawPath(context, kCGPathFillStroke); //根據(jù)坐標(biāo)繪制路徑

畫貝塞爾曲線

二次曲線

CGContextMoveToPoint(context, 120, 300);//設(shè)置Path的起點(diǎn)  
CGContextAddQuadCurveToPoint(context,190, 310, 120, 390);//設(shè)置貝塞爾曲線的控制點(diǎn)坐標(biāo)和終點(diǎn)坐標(biāo)  
CGContextStrokePath(context);  

三次曲線函數(shù)

CGContextMoveToPoint(context, 200, 300);//設(shè)置Path的起點(diǎn)  
CGContextAddCurveToPoint(context,250, 280, 250, 400, 280, 300);//設(shè)置貝塞爾曲線的控制點(diǎn)坐標(biāo)(2個(gè))和終點(diǎn)坐標(biāo)
CGContextStrokePath(context); 

畫圖片

UIImage *image = [UIImage imageNamed:@"apple.jpg"];
[image drawInRect:CGRectMake(60, 340, 20, 20)];//在坐標(biāo)中畫出圖片

圖形上下文棧的操作

將當(dāng)前的上下文copy一份,保存到棧頂(那個(gè)棧叫做”圖形上下文椈つ罚”)

void CGContextSaveGState(CGContextRef c)

將棧頂?shù)纳舷挛某鰲?替換掉當(dāng)前的上下文

void CGContextRestoreGState(CGContextRef c)

矩陣操作

利用矩陣操作矾端,能讓繪制到上下文中的所有路徑一起發(fā)生變化

縮放

void CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy)

旋轉(zhuǎn)

void CGContextRotateCTM(CGContextRef c, CGFloat angle)

平移

void CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)


想了解更多內(nèi)容,可以點(diǎn)擊以下鏈接:

http://blog.csdn.net/rhljiayou/article/details/9919713

http://www.reibang.com/p/0e785269dccc


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末卵皂,一起剝皮案震驚了整個(gè)濱河市秩铆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌灯变,老刑警劉巖殴玛,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異柒凉,居然都是意外死亡族阅,警方通過(guò)查閱死者的電腦和手機(jī)篓跛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門膝捞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人愧沟,你說(shuō)我怎么就攤上這事蔬咬。” “怎么了沐寺?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵林艘,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我混坞,道長(zhǎng)狐援,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任究孕,我火速辦了婚禮啥酱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘厨诸。我一直安慰自己镶殷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布微酬。 她就那樣靜靜地躺著绘趋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪颗管。 梳的紋絲不亂的頭發(fā)上陷遮,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音垦江,去河邊找鬼帽馋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的茬斧。 我是一名探鬼主播腰懂,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼项秉!你這毒婦竟也來(lái)了绣溜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤娄蔼,失蹤者是張志新(化名)和其女友劉穎怖喻,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岁诉,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锚沸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了涕癣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哗蜈。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖坠韩,靈堂內(nèi)的尸體忽然破棺而出距潘,到底是詐尸還是另有隱情,我是刑警寧澤只搁,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布音比,位于F島的核電站,受9級(jí)特大地震影響氢惋,放射性物質(zhì)發(fā)生泄漏洞翩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一焰望、第九天 我趴在偏房一處隱蔽的房頂上張望骚亿。 院中可真熱鬧,春花似錦柿估、人聲如沸循未。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)的妖。三九已至,卻和暖如春足陨,著一層夾襖步出監(jiān)牢的瞬間嫂粟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工墨缘, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留星虹,地道東北人零抬。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像宽涌,于是被迫代替她去往敵國(guó)和親平夜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • Quartz2D 簡(jiǎn)介及用途 Quartz 2D 是一個(gè)二維繪圖引擎卸亮,同時(shí)支持iOS和Mac系統(tǒng)忽妒,Quartz2D...
    45b645c5912e閱讀 967評(píng)論 1 16
  • Quartz2D以及drawRect的重繪機(jī)制字?jǐn)?shù)1487 閱讀21 評(píng)論1 喜歡1一、什么是Quartz2D Q...
    PurpleWind閱讀 771評(píng)論 0 3
  • --繪圖與濾鏡全面解析 概述 在iOS中可以很容易的開發(fā)出絢麗的界面效果兼贸,一方面得益于成功系統(tǒng)的設(shè)計(jì)段直,另一方面得益...
    韓七夏閱讀 2,726評(píng)論 2 10
  • 什么是Quartz2D? Quartz 2D是一個(gè)二維繪圖引擎,同時(shí)支持iOS和Mac系統(tǒng) Quartz 2D能完...
    Ljson閱讀 11,538評(píng)論 2 83
  • 一個(gè)人窮甩苛,一定是因?yàn)樗哪芰︴彘埂⑵返隆⑿闹菬o(wú)法駕馭財(cái)富讯蒲,所以財(cái)富才會(huì)離他遠(yuǎn)去。當(dāng)你優(yōu)秀了肄扎,物質(zhì)財(cái)富會(huì)不請(qǐng)自來(lái)墨林。股票也...
    唐驍伊閱讀 219評(píng)論 0 0