看了幾篇網(wǎng)上圖形上下文棧的講解卿闹,不知道是我理解有問題揭糕,還是沒找到好文章萝快,還是壓根作者也不是特別明白,欺騙我著角。最后決定自己寫一個(gè)demo揪漩,好好理解一下
什么是圖像上下文棧?
我的理解就是吏口,保存當(dāng)前的上下文樣式奄容,當(dāng)需要的時(shí)候直接還原,不用一直寫垃圾代碼
- (void)drawRect:(CGRect)rect {
//圖形上下文棧
CGContextRef ctx = UIGraphicsGetCurrentContext();
//第一根線产徊,頭部是圓角昂勒,線是紅色的,線寬10px
CGContextMoveToPoint(ctx, 10, 10);
CGContextAddLineToPoint(ctx, 10, 90);
CGContextSetLineCap(ctx, kCGLineCapRound);
CGContextSetLineWidth(ctx, 4);
[[UIColor redColor] set];
//保存第一個(gè)圖形上下文樣式
CGContextSaveGState(ctx);
CGContextStrokePath(ctx);
//第2根線,頭部是直角舟铜,線是綠色的,線寬10px
CGContextMoveToPoint(ctx, 30, 10);
CGContextAddLineToPoint(ctx, 30, 43);
CGContextSetLineWidth(ctx, 12);
CGContextSetLineCap(ctx, kCGLineCapButt);
[[UIColor greenColor] set];
//保存第二個(gè)圖形上下文樣式
CGContextSaveGState(ctx);
CGContextStrokePath(ctx);
//第3根線戈盈,頭部是kCGLineCapSquare,線是橙色的,線寬20px
CGContextMoveToPoint(ctx, 60, 40);
CGContextAddLineToPoint(ctx, 40, 180);
CGContextSetLineWidth(ctx, 4);
CGContextSetLineCap(ctx, kCGLineCapSquare);
[[UIColor orangeColor] set];
//保存第三個(gè)圖形上下文樣式
CGContextSaveGState(ctx);
CGContextStrokePath(ctx);
//直接繪制一個(gè)直線谆刨,看看是什么樣子的(其實(shí)是和第三個(gè)樣式相同)
CGContextMoveToPoint(ctx, 90, 10);
CGContextAddLineToPoint(ctx, 90, 99);
CGContextStrokePath(ctx);
//從圖像上下文中獲取一個(gè)數(shù)據(jù)試試
CGContextRestoreGState(ctx);
CGContextMoveToPoint(ctx, 120, 10);
CGContextAddLineToPoint(ctx, 120, 130);
CGContextStrokePath(ctx);
//突然想繪制第四個(gè)線塘娶,和第一根線一樣
CGContextMoveToPoint(ctx, 140, 10);
CGContextAddLineToPoint(ctx, 140, 99);
CGContextStrokePath(ctx);
//突然想繪制一個(gè)圓形,和第一根線的屬性基本一致
//即使使用一個(gè)圖形上下文痊夭,也不影響使用屬性和繪制多個(gè)圖形
CGContextAddArc(ctx, 200, 60, 20, 0, 189/360.0*2*M_PI, NO);
CGContextStrokePath(ctx);
//從圖形上下文棧中在獲取一個(gè)試試
CGContextRestoreGState(ctx);
CGContextMoveToPoint(ctx, 250, 10);
CGContextAddLineToPoint(ctx, 250, 100);
CGContextStrokePath(ctx);
![Uploading Simulator Screen Shot 2016年8月7日 下午12.55.32_489724.png . . .]
//再去從圖形上下文棧中在獲取一個(gè)
CGContextRestoreGState(ctx);
CGContextMoveToPoint(ctx, 300, 10);
CGContextAddLineToPoint(ctx, 300, 100);
CGContextStrokePath(ctx);
}
注意:
1.入棧CGContextSaveGState(cox)
2.出棧CGContextRestoreGState(ctx);
3.如果出戰(zhàn)的次數(shù)大于入棧刁岸,就會(huì)奔潰
4.什么是入棧?就是拷貝當(dāng)前圖形上下文她我,然后放到棧中虹曙,因?yàn)槭褂?code>CGContextRef,只有一個(gè)圖形上下文鸦难,所以要拷貝根吁!
5.如何理解拷貝圖形上下文,我們操作的圖形上下文成為A,此時(shí)如果圖形上下文就設(shè)置了[[UIColor redColor] set]
這一個(gè)屬性合蔽,拷貝A击敌,入棧(我們把拷貝后入棧的成為B),將來不論以后我們?nèi)绾尾僮鰽拴事,設(shè)置了多少屬性沃斤,以后的都是A這個(gè)模樣,但是我們出戰(zhàn)B刃宵,將來使用的樣式都是只有一個(gè)[[UIColor redColor] set]
的狀態(tài)衡瓶!說白了,就是保存某種圖形上下文的狀態(tài)牲证!
5.出戰(zhàn)的上下文哮针,將樣式賦值給當(dāng)前樣式,然后釋放