這邊從iOS繪圖教程 提取一些重要的內容。html
Core Graphics Framework是一套基於C的API框架,使用了Quartz做爲繪圖引擎。iOS支持兩套圖形API族:Core Graphics/QuartZ 2D 和OpenGL ES。git
Core Graphics API全部的操做都在一個上下文中進行。因此在繪圖以前須要獲取該上下文並傳入執行渲染的函數中。若是你正在渲染一副在內存中的圖片,此時就須要傳入圖片所屬的上下文。得到一個圖形上下文是咱們完成繪圖任務的第一步,你能夠將圖形上下文理解爲一塊畫布。若是你沒有獲得這塊畫布,那麼你就沒法完成任何繪圖操做。固然,有許多方式得到一個圖形上下文,這裏我介紹兩種最爲經常使用的獲取方法。github
建立一個圖片類型的上下文。調用UIGraphicsBeginImageContextWithOptions
函數就可得到用來處理圖片的圖形上下文。利用該上下文,你就能夠在其上進行繪圖,並生成圖片。調用UIGraphicsGetImageFromCurrentImageContext
函數可從當前上下文中獲取一個UIImage對象。記住在你全部的繪圖操做後別忘了調用UIGraphicsEndImageContext
函數關閉圖形上下文。框架
利用cocoa爲你生成的圖形上下文。當你子類化了一個UIView並實現了本身的drawRect:
方法後,一旦drawRect:
方法被調用,Cocoa就會爲你建立一個圖形上下文,此時你對圖形上下文的全部繪圖操做都會顯示在UIView上。函數
判斷一個上下文是否爲當前圖形上下文須要注意的幾點:ui
UIGraphicsBeginImageContextWithOptions
函數不單單是建立了一個適用於圖形操做的上下文,而且該上下文也屬於當前上下文。drawRect
方法被調用時,UIView的繪圖上下文屬於當前圖形上下文。做爲初學者,很容易被UIKit和Core Graphics兩個支持繪圖的框架迷惑。spa
像UIImage、NSString(繪製文本)、UIBezierPath(繪製形狀)、UIColor都知道如何繪製本身。這些類提供了功能有限但使用方便的方法來讓咱們完成繪圖任務。通常狀況下,UIKit就是咱們所須要的。.net
使用UiKit,你只能在當前上下文中繪圖,因此若是你當前處於UIGraphicsBeginImageContextWithOptions
函數或drawRect:
方法中,你就能夠直接使用UIKit提供的方法進行繪圖。若是你持有一個context:參數,那麼使用UIKit提供的方法以前,必須將該上下文參數轉化爲當前上下文。幸運的是,調用UIGraphicsPushContext
函數能夠方便的將context:參數轉化爲當前上下文,記住最後別忘了調用UIGraphicsPopContext函數恢復上下文環境。翻譯
這是一個繪圖專用的API族,它常常被稱爲QuartZ或QuartZ 2D。Core Graphics是iOS上全部繪圖功能的基石,包括UIKit。code
使用Core Graphics以前須要指定一個用於繪圖的圖形上下文(CGContextRef),這個圖形上下文會在每一個繪圖函數中都會被用到。若是你持有一個圖形上下文context:參數,那麼你等同於有了一個圖形上下文,這個上下文也許就是你須要用來繪圖的那個。若是你當前處於UIGraphicsBeginImageContextWithOptions
函數或drawRect:
方法中,並無引用一個上下文。爲了使用Core Graphics,你能夠調用UIGraphicsGetCurrentContext
函數得到當前的圖形上下文。
在stackoverflow上,有這樣一個問題CGContextSaveGState vs UIGraphicsPushContext問了二者區別,這裏列一下高票答案:
UIGraphicsPushContext(context) pushes context onto a stack of CGContextRefs (making context the current drawing context), whereas CGContextSaveGState(context) pushes the current graphics state onto the stack of graphics states maintained by context. You should use UIGraphicsPushContext if you need to make a new CGContextRef the current drawing context, and you should use CGContextSaveGState when you're working with one graphics context and just want to save, for example: the current transform state, fill or stroke colors, etc.
翻譯一下就是:
UIGraphicsPushContext(context)
將context壓到一個CGContextRefs(使得context成爲current context)的棧中。而CGContextSaveGState(context)
將當前繪製狀態壓到一個context維護的繪製狀態的棧中。你可使用UIGraphicsPushContext
當你須要在當前的context去建立一個新的CGContextRef,同時你可使用CGContextSaveGState
當你在處理一個繪製context而且只是想保存的它的時候。好比:當前的變換狀態,填充或者線條顏色等。
以上答案其實就是在說:
UIGraphicsPushContext
:壓棧當前的繪製對象,生成新的繪製圖層CGContextSaveGState
:壓棧當前的繪製狀態咱們這裏用一段實際代碼:
-(void)drawRect:(CGRect)rect{ CGContextRef ctx=UIGraphicsGetCurrentContext(); [[UIColor redColor] setStroke]; //紅色 CGContextSaveGState(UIGraphicsGetCurrentContext()); CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 50, 50)); CGContextSetLineWidth(ctx, 10); [[UIColor yellowColor] setStroke]; //黃色 CGContextStrokePath(ctx); CGContextRestoreGState(UIGraphicsGetCurrentContext()); CGContextAddEllipseInRect(ctx, CGRectMake(200, 100, 50, 50)); //紅色 CGContextStrokePath(ctx); }
運行一下看結果:
能夠看到,CGContextSaveGState
存儲下來了當前紅色和默認的線條狀態,而後切換顏色到黃色和10粗度的線條畫圈,而後在CGContextRestoreGState
恢復到了紅色和默認的線條狀態進行畫圈,這個就是存儲當前繪製狀態的意思。
一樣用一段實際代碼:
- (void)viewDidLoad { [super viewDidLoad]; CALayer *layer=[CALayer layer]; layer.bounds=CGRectMake(0, 0, 300, 300); layer.position=CGPointMake(100, 100); layer.delegate=self; [layer setNeedsDisplay]; [self.view.layer addSublayer:layer]; } -(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{ UIImage *image = [UIImage imageNamed:@"test.jpg"]; UIGraphicsPushContext(ctx); [image drawInRect:CGRectMake(0, 0, 300, 300)]; UIGraphicsPopContext(); }
運行看一下結果:
若是你將UIGraphicsPushContext(ctx);
與UIGraphicsPopContext();
刪去的話,是沒法進行繪製的。
緣由是,UIKit的繪製必須在當前的上下文中繪製,而UIGraphicsPushContext能夠將當前的參數context轉化爲能夠UIKit繪製的上下文,進行繪製圖片。
CGContextSaveGState
是壓棧當前的繪製狀態,而UIGraphicsPushContext
:壓棧當前的繪製對象,生成新的繪製圖層。對於UIGraphicsPushContext
的使用,不少都是與UIKit配合使用,更詳細的對於CoreGraphics的介紹,能夠參考iOS繪圖教程 。
1.CGContextSaveGState vs UIGraphicsPushContext
2.iOS --- CoreGraphics中三種繪圖context切換方式的區別
3.iOS core graphic使用分析
4.iOS繪圖教程 | iOS繪圖教程