高低文棧
1、qurza2d是怎樣將畫圖信息和畫圖的屬性繪制到圖形高低文中去的?
解釋:
新建一個項目,自界說一個view類和storyboard聯系關系後,重寫該類中的drowrect辦法。
畫線的三個步調:
(1)獲得高低文
(2)畫圖
(3)襯著
請求:畫兩條零丁的線
代碼和後果圖:
- (void)drawRect:(CGRect)rect
{
//獲得高低文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//畫圖
//第一條線
CGContextMoveToPoint(ctx, 20, 100);
CGContextAddL.netoPoint(ctx, 100, 320);
//第二條線
CGContextMoveToPoint(ctx, 40, 200);
CGContextAddL.netoPoint(ctx, 80, 100);
//襯著
CGContextStrokePath(ctx);
}
後果圖:
設置線段的寬度:兩端為圓形,色彩等。
代碼和後果圖(發明第二條線也被襯著成第一條線的款式和狀況)
- (void)drawRect:(CGRect)rect
{
//獲得高低文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//畫圖
//第一條線
CGContextMoveToPoint(ctx, 20, 100);
CGContextAddL.netoPoint(ctx, 100, 320);
//設置第一條線的狀況
//設置線條的寬度
CGContextSetLineWidth(ctx, 12);
//設置線條的色彩
[[UIColor brownColor]set];
//設置線條兩頭的款式為圓角
CGContextSetLineCap(ctx,kCGLineCapRound);
//對線條停止襯著
CGContextStrokePath(ctx);
//第二條線
CGContextMoveToPoint(ctx, 40, 200);
CGContextAddLineToPoint(ctx, 80, 100);
//襯著
CGContextStrokePath(ctx);
}
後果圖:
新的需求:要讓兩條線的色彩紛歧樣,請求第二條線釀成原版的模樣。要到達下面的請求,有以下幾種做法:
第一種做法:
在對第二條線停止設置的時刻,清空它的狀況
- (void)drawRect:(CGRect)rect
{
//獲得高低文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//畫圖
//第一條線
CGContextMoveToPoint(ctx, 20, 100);
CGContextAddLineToPoint(ctx, 100, 320);
//設置第一條線的狀況
//設置線條的寬度
CGContextSetLineWidth(ctx, 12);
//設置線條的色彩
[[UIColor brownColor]set];
//設置線條兩頭的款式為圓角
CGContextSetLineCap(ctx,kCGLineCapRound);
//對線條停止襯著
CGContextStrokePath(ctx);
//第二條線
CGContextMoveToPoint(ctx, 40, 200);
CGContextAddLineToPoint(ctx, 80, 100);
//清空狀況
CGContextSetLineWidth(ctx, 1);
[[UIColor blackColor]set];
CGContextSetLineCap(ctx,kCGLineCapButt);
//襯著
CGContextStrokePath(ctx);
}
第二種做法:
把第一條線從開端繪制到襯著的代碼剪切到第二條線襯著完成以後,如許先繪制並襯著了第一條線,該線並沒有對繪制信息停止過設置,顯示出來的第二條線即位體系默許的後果。
- (void)drawRect:(CGRect)rect
{
//獲得高低文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//畫圖
//第二條線
CGContextMoveToPoint(ctx, 40, 200);
CGContextAddLineToPoint(ctx, 80, 100);
//清空狀況
// CGContextSetLineWidth(ctx, 1);
// [[UIColor blackColor]set];
// CGContextSetLineCap(ctx,kCGLineCapButt);
//襯著
CGContextStrokePath(ctx);
//第一條線
CGContextMoveToPoint(ctx, 20, 100);
CGContextAddLineToPoint(ctx, 100, 320);
//設置第一條線的狀況
//設置線條的寬度
CGContextSetLineWidth(ctx, 12);
//設置線條的色彩
[[UIColor brownColor]set];
//設置線條兩頭的款式為圓角
CGContextSetLineCap(ctx,kCGLineCapRound);
//對線條停止襯著
CGContextStrokePath(ctx);
}
兩種方法完成的後果雷同:
然則有的情形下,必需要先畫第一條線再畫第二條線,請求在穿插部門,第二條線蓋在第一條線的下面。假如請求是如許,那末只能應用第一種做法,然則假如如今有新的需求,請求在這個基本上再畫兩條線,那就須要清空ctx中的狀況許多次,很費事。為懂得決這個成績,上面給年夜家引見圖形高低文棧。
2、畫圖的完全進程
法式啟動,顯示自界說的view。當法式第一次顯示在我們面前的時刻,法式會挪用drawRect:辦法,在外面獲得了圖形高低文(在內存中具有了),然後應用圖形高低文保留畫圖信息,可以懂得為圖形高低文中有一塊區域用來保留畫圖信息,有一塊區域用來保留畫圖的狀況(線寬,圓角,色彩)。直線不是直接繪制到view上的,可以懂得為在圖形高低文中有一塊零丁的區域用來先繪制圖形,當挪用襯著辦法的時刻,再把繪制好的圖形顯示到view上去。
在繪制圖形區域,會去保留畫圖狀況區域中查找對應的狀況信息(線寬,圓角,色彩),然後在畫圖區域把對第一條直線繪制完成。其其實襯著之前,就曾經把直線在繪制圖形區域畫好了。
如圖:
解釋:這些表示圖和本文中的法式代碼塊,不具有逐個對應關系,只是為了解釋畫圖的完全進程。
挪用襯著辦法的時刻,把繪制圖形區域曾經畫好的圖形直接顯示到view上,就是我們看到的模樣了。
如圖:
畫第二條的時刻,假如沒有對畫圖狀況停止從新設置,那末可以發明畫第一天線的時刻應用的畫圖狀況還保留在圖形高低文中,在第二條線停止襯著之前,會依據第一條線(上一份畫圖狀況)對第二條線停止響應的設置,襯著後把第二條線顯示到屏幕上。
參考代碼:
- (void)drawRect:(CGRect)rect
{
//獲得高低文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//畫圖
//第一條線
CGContextMoveToPoint(ctx, 20, 100);
CGContextAddLineToPoint(ctx, 100, 320);
//設置第一條線的狀況
//設置線條的寬度
CGContextSetLineWidth(ctx, 12);
//設置線條的色彩
[[UIColor brownColor]set];
//設置線條兩頭的款式為圓角
CGContextSetLineCap(ctx,kCGLineCapRound);
//對線條停止襯著
CGContextStrokePath(ctx);
//第二條線
CGContextMoveToPoint(ctx, 40, 200);
CGContextAddLineToPoint(ctx, 80, 100);
//襯著
CGContextStrokePath(ctx);
}
假如清空了狀況,則在襯著之前,在繪制圖形區域對第二條線停止繪制的時刻,會去查找以後的畫圖信息(曾經更改——清空),依據畫圖信息對第二條線停止繪制,挪用襯著辦法的時刻把第二條線顯示到view上。
參考代碼:
- (void)drawRect:(CGRect)rect
{
//獲得高低文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//畫圖
//第一條線
CGContextMoveToPoint(ctx, 20, 100);
CGContextAddLineToPoint(ctx, 100, 320);
//設置第一條線的狀況
//設置線條的寬度
CGContextSetLineWidth(ctx, 12);
//設置線條的色彩
[[UIColor brownColor]set];
//設置線條兩頭的款式為圓角
CGContextSetLineCap(ctx,kCGLineCapRound);
//對線條停止襯著
CGContextStrokePath(ctx);
//第二條線
CGContextMoveToPoint(ctx, 40, 200);
CGContextAddLineToPoint(ctx, 80, 100);
//清空狀況
CGContextSetLineWidth(ctx, 1);
[[UIColor blackColor]set];
CGContextSetLineCap(ctx,kCGLineCapButt);
//襯著
CGContextStrokePath(ctx);
}
3、圖形高低文棧
1.簡略解釋
在獲得圖形高低文以後,經由過程 CGContextSaveGState(ctx); 辦法,把以後獲得的高低文拷貝一份,保留一份最純粹的圖形高低文。
在畫第二條線之前,應用CGContextRestoreGState(ctx);辦法,復原開端的時刻保留的那份最純粹的圖形高低文。
代碼:
- (void)drawRect:(CGRect)rect
{
//獲得高低文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//保留一份最後的圖形高低文
CGContextSaveGState(ctx);
//畫圖
//第一條線
CGContextMoveToPoint(ctx, 20, 100);
CGContextAddLineToPoint(ctx, 100, 320);
//設置第一條線的狀況
//設置線條的寬度
CGContextSetLineWidth(ctx, 12);
//設置線條的色彩
[[UIColor brownColor]set];
//設置線條兩頭的款式為圓角
CGContextSetLineCap(ctx,kCGLineCapRound);
//對線條停止襯著
CGContextStrokePath(ctx);
//復原開端的時刻保留的那份最純粹的圖形高低文
CGContextRestoreGState(ctx);
//第二條線
CGContextMoveToPoint(ctx, 40, 200);
CGContextAddLineToPoint(ctx, 80, 100);
//清空狀況
// CGContextSetLineWidth(ctx, 1);
// [[UIColor blackColor]set];
// CGContextSetLineCap(ctx,kCGLineCapButt);
//襯著
CGContextStrokePath(ctx);
}
2.圖形高低文棧機制
畫第一條線的時刻,會把以後的圖形高低文拷貝一份保留到圖形高低文棧中。
畫第二條線的時刻,去圖形高低文棧中掏出棧頂的畫圖信息,作為第二條線的狀況信息,第二條線的狀況信息也是據此(最後保留的那份圖形高低文)停止繪制。
留意:在棧裡保留了幾回,那末便可以取幾回(好比不克不及保留了1次,取兩次,在取第二次的時刻,棧裡為空會直接掛失落)。
矩陣操作
1、關於矩陣操作
1.畫一個四邊形
經由過程設置兩個端點(長和寬)來完成一個四邊形的繪制。
代碼:
- (void)drawRect:(CGRect)rect
{
//畫四邊形
//獲得圖形高低文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//畫圖
CGContextAddRect(ctx, CGRectMake(20, 50, 100, 100));
//襯著
CGContextStrokePath(ctx);
}
解釋:經由過程這類方法畫矩形有弱點:畫出來的矩形永久都是正的。以下圖:
2.畫一個歪的四邊形
若何畫一個歪的矩形?(經由過程矩陣操作來完成,和形變操作類似)
可以經由過程矩陣操作,把畫出來的器械停止形變(扭轉,縮放,平移)
辦法:CGContextRotateCTM(<#CGContextRef C#>, <#CGFloat angle#>)該接收兩個參數(圖形高低文,弧度)
留意點:設置矩陣操作必需要在添加圖形之前,假如設置在添加圖形以後的話,此時它曾經畫完了,有效。
代碼:
- (void)drawRect:(CGRect)rect
{
//畫四邊形
//獲得圖形高低文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//矩陣操作
//留意點:設置矩陣操作必需要在添加畫圖信息之前
//扭轉45度
CGContextRotateCTM(ctx, M_PI_4);
//畫圖
CGContextAddRect(ctx, CGRectMake(150, 100, 100, 100));
//襯著
CGContextStrokePath(ctx);
}
後果:
2、關於扭轉
1.扭轉演示
view之所以可以或許顯示視圖,是由於它的下面有layer,未來圖形也是襯著到layer下面。
且,扭轉的時刻是全部layer都扭轉了,可以再畫一個圓停止驗證。
代碼1(未扭轉):
- (void)drawRect:(CGRect)rect
{
//獲得圖形高低文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//矩陣操作
//留意點:設置矩陣操作必需要在添加畫圖信息之前
//扭轉45度
// CGContextRotateCTM(ctx, M_PI_4);
//畫圖
//畫四邊形
CGContextAddRect(ctx, CGRectMake(150, 100, 100, 100));
//畫一個圓
CGContextAddEllipseInRect(ctx, CGRectMake(200, 200, 50, 50));
//襯著
CGContextStrokePath(ctx);
}
後果:
代碼2(扭轉):
- (void)drawRect:(CGRect)rect
{
//獲得圖形高低文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//矩陣操作
//留意點:設置矩陣操作必需要在添加畫圖信息之前
//扭轉45度
CGContextRotateCTM(ctx, M_PI_4);
//畫圖
//畫四邊形
CGContextAddRect(ctx, CGRectMake(150, 100, 100, 100));
//畫一個圓
CGContextAddEllipseInRect(ctx, CGRectMake(200, 200, 50, 50));
//襯著
CGContextStrokePath(ctx);
}
後果:
2.關於扭轉的彌補解釋
提醒:扭轉的時刻,是全部layer都扭轉了。
3、縮放
辦法:CGContextScaleCTM(<#CGContextRef C#>, <#CGFloat sx#>, <#CGFloat sy#>)
該辦法吸收三個參數(圖形高低文,x偏向的縮放比例,y偏向上的縮放比例
代碼示例:
- (void)drawRect:(CGRect)rect
{
//獲得圖形高低文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//矩陣操作
//留意點:設置矩陣操作必需要在添加畫圖信息之前
//縮放,x偏向縮放0.5倍,y偏向縮放1.5倍
CGContextScaleCTM(ctx, 0.5, 1.5);
//畫圖
//畫四邊形
CGContextAddRect(ctx, CGRectMake(150, 100, 100, 100));
//畫一個圓
CGContextAddEllipseInRect(ctx, CGRectMake(200, 200, 50, 50));
//襯著
CGContextStrokePath(ctx);
}
後果:
4、平移
辦法: CGContextTranslateCTM(<#CGContextRef C#>, <#CGFloat tx#>, <#CGFloat ty#>)
該辦法吸收三個參數(圖形高低文,x偏向的偏移量,y偏向上的偏移量)
代碼示例:
- (void)drawRect:(CGRect)rect
{
//獲得圖形高低文
CGContextRef ctx=UIGraphicsGetCurrentContext();
//矩陣操作
//留意點:設置矩陣操作必需要在添加畫圖信息之前
//平移,x偏向挪動50,y偏向挪動100
CGContextTranslateCTM(ctx, 50, 100);
//畫圖
//畫四邊形
CGContextAddRect(ctx, CGRectMake(150, 100, 100, 100));
//畫一個圓
CGContextAddEllipseInRect(ctx, CGRectMake(200, 200, 50, 50));
//襯著
CGContextStrokePath(ctx);
}
後果:
提醒:坐標原點為view的左上角。
【iOS開辟中應用Quartz2D繪制高低文棧和矩陣的辦法】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!