一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

iOS開發(fā)UI篇—Quartz2D使用(圖形上下文棧)

 印度阿三17 2019-02-05

?

 1 - (void)drawRect:(CGRect)rect
 2 {
 3     //獲取上下文
 4     CGContextRef ctx=UIGraphicsGetCurrentContext();
 5     //繪圖
 6     //第一條線
 7     CGContextMoveToPoint(ctx, 20, 100);
 8     CGContextAddLineToPoint(ctx, 100, 320);
 9     
10     //設(shè)置第一條線的狀態(tài)
11     //設(shè)置線條的寬度
12     CGContextSetLineWidth(ctx, 12);
13     //設(shè)置線條的顏色
14     [[UIColor brownColor]set];
15     //設(shè)置線條兩端的樣式為圓角
16     CGContextSetLineCap(ctx,kCGLineCapRound);
17     //對(duì)線條進(jìn)行渲染
18     CGContextStrokePath(ctx);
19     
20     //第二條線
21     CGContextMoveToPoint(ctx, 40, 200);
22     CGContextAddLineToPoint(ctx, 80, 100);
23     //渲染
24     CGContextStrokePath(ctx);
25     
26 }

效果圖:

新的需求:要讓兩條線的顏色不一樣,要求第二條線變成原版的樣子。要達(dá)到上面的要求,有以下幾種做法:

第一種做法:

在對(duì)第二條線進(jìn)行設(shè)置的時(shí)候,清空它的狀態(tài)

 1 - (void)drawRect:(CGRect)rect
 2 {
 3     //獲取上下文
 4     CGContextRef ctx=UIGraphicsGetCurrentContext();
 5     //繪圖
 6     //第一條線
 7     CGContextMoveToPoint(ctx, 20, 100);
 8     CGContextAddLineToPoint(ctx, 100, 320);
 9     
10     //設(shè)置第一條線的狀態(tài)
11     //設(shè)置線條的寬度
12     CGContextSetLineWidth(ctx, 12);
13     //設(shè)置線條的顏色
14     [[UIColor brownColor]set];
15     //設(shè)置線條兩端的樣式為圓角
16     CGContextSetLineCap(ctx,kCGLineCapRound);
17     //對(duì)線條進(jìn)行渲染
18     CGContextStrokePath(ctx);
19     
20     //第二條線
21     CGContextMoveToPoint(ctx, 40, 200);
22     CGContextAddLineToPoint(ctx, 80, 100);
23     
24     //清空狀態(tài)
25     CGContextSetLineWidth(ctx, 1);
26     [[UIColor blackColor]set];
27     CGContextSetLineCap(ctx,kCGLineCapButt);
28     
29     //渲染
30     CGContextStrokePath(ctx);
31     
32 }

第二種做法:

把第一條線從開始繪制到渲染的代碼剪切到第二條線渲染完成之后,這樣先繪制并渲染了第一條線,該線并沒有對(duì)繪制信息進(jìn)行過設(shè)置,顯示出來的第二條線即位系統(tǒng)默認(rèn)的效果。

 1 - (void)drawRect:(CGRect)rect
 2 {
 3     //獲取上下文
 4     CGContextRef ctx=UIGraphicsGetCurrentContext();
 5     //繪圖
 6     
 7     //第二條線
 8     CGContextMoveToPoint(ctx, 40, 200);
 9     CGContextAddLineToPoint(ctx, 80, 100);
10     
11     //清空狀態(tài)
12     //    CGContextSetLineWidth(ctx, 1);
13     //    [[UIColor blackColor]set];
14     
15     //    CGContextSetLineCap(ctx,kCGLineCapButt);
16     
17     //渲染
18     CGContextStrokePath(ctx);
19     
20     //第一條線
21     CGContextMoveToPoint(ctx, 20, 100);
22     CGContextAddLineToPoint(ctx, 100, 320);
23     
24     //設(shè)置第一條線的狀態(tài)
25     //設(shè)置線條的寬度
26     CGContextSetLineWidth(ctx, 12);
27     //設(shè)置線條的顏色
28     [[UIColor brownColor]set];
29     //設(shè)置線條兩端的樣式為圓角
30     CGContextSetLineCap(ctx,kCGLineCapRound);
31     //對(duì)線條進(jìn)行渲染
32     CGContextStrokePath(ctx);
33 }

兩種方式完成的效果相同:

但是有的情況下,必須要先畫第一條線再畫第二條線,要求在交叉部分,第二條線蓋在第一條線的上面。如果要求是這樣,那么只能使用第一種做法,但是如果現(xiàn)在有新的需求,要求在這個(gè)基礎(chǔ)上再畫兩條線,那就需要清空ctx中的狀態(tài)很多次,很麻煩。為了解決這個(gè)問題,下面給大家介紹圖形上下文棧。

二、繪圖的完整過程

程序啟動(dòng),顯示自定義的view。當(dāng)程序第一次顯示在我們眼前的時(shí)候,程序會(huì)調(diào)用drawRect:方法,在里面獲取了圖形上下文(在內(nèi)存中擁有了),然后利用圖形上下文保存繪圖信息,可以理解為圖形上下文中有一塊區(qū)域用來保存繪圖信息,有一塊區(qū)域用來保存繪圖的狀態(tài)(線寬,圓角,顏色)。直線不是直接繪制到view上的,可以理解為在圖形上下文中有一塊單獨(dú)的區(qū)域用來先繪制圖形,當(dāng)調(diào)用渲染方法的時(shí)候,再把繪制好的圖形顯示到view上去。

在繪制圖形區(qū)域,會(huì)去保存繪圖狀態(tài)區(qū)域中查找對(duì)應(yīng)的狀態(tài)信息(線寬,圓角,顏色),然后在繪圖區(qū)域把對(duì)第一條直線繪制完成。其實(shí)在渲染之前,就已經(jīng)把直線在繪制圖形區(qū)域畫好了。

如圖:

說明:這些示意圖和本文中的程序代碼塊,不具備一一對(duì)應(yīng)關(guān)系,只是為了說明繪圖的完整過程。

調(diào)用渲染方法的時(shí)候,把繪制圖形區(qū)域已經(jīng)畫好的圖形直接顯示到view上,就是我們看到的樣子了。

如圖:

畫第二條的時(shí)候,如果沒有對(duì)繪圖狀態(tài)進(jìn)行重新設(shè)置,那么可以發(fā)現(xiàn)畫第一天線的時(shí)候使用的繪圖狀態(tài)還保存在圖形上下文中,在第二條線進(jìn)行渲染之前,會(huì)根據(jù)第一條線(上一份繪圖狀態(tài))對(duì)第二條線進(jìn)行相應(yīng)的設(shè)置,渲染后把第二條線顯示到屏幕上。

參考代碼:

 1 - (void)drawRect:(CGRect)rect
 2 {
 3     //獲取上下文
 4     CGContextRef ctx=UIGraphicsGetCurrentContext();
 5     //繪圖
 6     //第一條線
 7     CGContextMoveToPoint(ctx, 20, 100);
 8     CGContextAddLineToPoint(ctx, 100, 320);
 9     
10     //設(shè)置第一條線的狀態(tài)
11     //設(shè)置線條的寬度
12     CGContextSetLineWidth(ctx, 12);
13     //設(shè)置線條的顏色
14     [[UIColor brownColor]set];
15     //設(shè)置線條兩端的樣式為圓角
16     CGContextSetLineCap(ctx,kCGLineCapRound);
17     //對(duì)線條進(jìn)行渲染
18     CGContextStrokePath(ctx);
19     
20     //第二條線
21     CGContextMoveToPoint(ctx, 40, 200);
22     CGContextAddLineToPoint(ctx, 80, 100);
23     //渲染
24     CGContextStrokePath(ctx);
25 }

如果清空了狀態(tài),則在渲染之前,在繪制圖形區(qū)域?qū)Φ诙l線進(jìn)行繪制的時(shí)候,會(huì)去查找當(dāng)前的繪圖信息(已經(jīng)更改——清空),根據(jù)繪圖信息對(duì)第二條線進(jìn)行繪制,調(diào)用渲染方法的時(shí)候把第二條線顯示到view上。

參考代碼:

 1 - (void)drawRect:(CGRect)rect
 2 {
 3     //獲取上下文
 4     CGContextRef ctx=UIGraphicsGetCurrentContext();
 5     //繪圖
 6     //第一條線
 7     CGContextMoveToPoint(ctx, 20, 100);
 8     CGContextAddLineToPoint(ctx, 100, 320);
 9     
10     //設(shè)置第一條線的狀態(tài)
11     //設(shè)置線條的寬度
12     CGContextSetLineWidth(ctx, 12);
13     //設(shè)置線條的顏色
14     [[UIColor brownColor]set];
15     //設(shè)置線條兩端的樣式為圓角
16     CGContextSetLineCap(ctx,kCGLineCapRound);
17     //對(duì)線條進(jìn)行渲染
18     CGContextStrokePath(ctx);
19     
20     //第二條線
21     CGContextMoveToPoint(ctx, 40, 200);
22     CGContextAddLineToPoint(ctx, 80, 100);
23     
24     //清空狀態(tài)
25     CGContextSetLineWidth(ctx, 1);
26     [[UIColor blackColor]set];
27     CGContextSetLineCap(ctx,kCGLineCapButt);
28     
29     //渲染
30     CGContextStrokePath(ctx);
31 }

三、圖形上下文棧

1.簡(jiǎn)單說明

在獲取圖形上下文之后,通過

CGContextSaveGState(ctx);

方法,把當(dāng)前獲取的上下文拷貝一份,保存一份最純潔的圖形上下文。

在畫第二條線之前,使用CGContextRestoreGState(ctx);方法,還原開始的時(shí)候保存的那份最純潔的圖形上下文。

代碼:

 1 - (void)drawRect:(CGRect)rect
 2 {
 3     //獲取上下文
 4     CGContextRef ctx=UIGraphicsGetCurrentContext();
 5     //保存一份最初的圖形上下文
 6     CGContextSaveGState(ctx);
 7     
 8     //繪圖
 9     //第一條線
10     CGContextMoveToPoint(ctx, 20, 100);
11     CGContextAddLineToPoint(ctx, 100, 320);
12     
13     //設(shè)置第一條線的狀態(tài)
14     //設(shè)置線條的寬度
15     CGContextSetLineWidth(ctx, 12);
16     //設(shè)置線條的顏色
17     [[UIColor brownColor]set];
18     //設(shè)置線條兩端的樣式為圓角
19     CGContextSetLineCap(ctx,kCGLineCapRound);
20     //對(duì)線條進(jìn)行渲染
21     CGContextStrokePath(ctx);
22     
23     //還原開始的時(shí)候保存的那份最純潔的圖形上下文
24     CGContextRestoreGState(ctx);
25     //第二條線
26     CGContextMoveToPoint(ctx, 40, 200);
27     CGContextAddLineToPoint(ctx, 80, 100);
28     
29     //清空狀態(tài)
30 //    CGContextSetLineWidth(ctx, 1);
31 //    [[UIColor blackColor]set];
32 //    CGContextSetLineCap(ctx,kCGLineCapButt);
33     
34     //渲染
35     CGContextStrokePath(ctx);
36 }

2.圖形上下文棧機(jī)制

畫第一條線的時(shí)候,會(huì)把當(dāng)前的圖形上下文拷貝一份保存到圖形上下文棧中。

畫第二條線的時(shí)候,去圖形上下文棧中取出棧頂?shù)睦L圖信息,作為第二條線的狀態(tài)信息,第二條線的狀態(tài)信息也是據(jù)此(最初保存的那份圖形上下文)進(jìn)行繪制。

注意:在棧里保存了幾次,那么就可以取幾次(比如不能保存了1次,取兩次,在取第二次的時(shí)候,棧里為空會(huì)直接掛掉)。

來源:http://www./content-4-109751.html

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    久久精品国产亚洲av麻豆| 日本办公室三级在线观看| 日本男人女人干逼视频| 黄片免费播放一区二区| 成人免费在线视频大香蕉 | 九九视频通过这里有精品| 欧美精品一区二区水蜜桃| 黄片在线观看一区二区三区| 天堂热东京热男人天堂| 性感少妇无套内射在线视频| 日韩人妻毛片中文字幕| 国产一级精品色特级色国产| 亚洲国产性生活高潮免费视频| 欧美成人欧美一级乱黄| 老司机精品一区二区三区| 欧美日韩精品人妻二区三区 | 爱在午夜降临前在线观看| 欧美一区二区三区99| 中国黄色色片色哟哟哟哟哟哟| 日本女优一区二区三区免费| 欧美一区二区三区在线播放| 国产又粗又猛又长又黄视频| 午夜福利92在线观看| 国产日韩在线一二三区| 国产女同精品一区二区| 欧美日韩国产午夜福利| 欧美日韩国产免费看黄片| 国产成人精品午夜福利av免费| 国产户外勾引精品露出一区 | 91精品日本在线视频| 97精品人妻一区二区三区麻豆| 超薄肉色丝袜脚一区二区| 91国内视频一区二区三区| 亚洲国产av一二三区| 亚洲精品中文字幕欧美| 亚洲熟女一区二区三四区| 欧美在线观看视频免费不卡| 日本男人女人干逼视频| 亚洲中文字幕日韩在线| 中文久久乱码一区二区| 午夜国产精品福利在线观看|