什麼是Quartz2D
1、Quartz 2D 是一個二維繪圖引擎,同時支持iOS和Mac系統
2、Quartz 2D 能完成的工作:
-
繪製圖形 : 線條\三角形\矩形\圓\弧等
-
繪製文字
-
繪製\生成圖片(圖像)
-
讀取\生成PDF
-
截圖\裁剪圖片
-
自定義UI控件
圖形上下文
1、圖形上下文(Graphics Context):是一個 CGContextRef 類型的數據
2、圖形上下文的作用:
-
保存繪圖信息、繪圖狀態
-
決定繪製的輸出目標(繪製到什麼地方去?)
相同的一套繪圖序列,指定不同的 Graphics Context,就可將相同的圖像繪製到不同的目標上
3、Quartz2D 提供了以下幾種類型的 Graphics Context:
-
BitmapGraphics Context
-
PDFGraphics Context
-
WindowGraphics Context
-
LayerGraphics Context
-
PrinterGraphics Context
自定義view
1、如何利用 Quartz2D 繪製東西到 view 上?
-
首先,得有圖形上下文,因爲它能保存繪圖信息,並且決定着繪製到什麼地方去
-
其次,那個圖形上下文必須跟view相關聯,才能將內容繪製到view上面
2、自定義view的步驟
-
新建一個類,繼承自 UIView
-
實現 - (void)drawRect:(CGRect)rect 方法,然後在這個方法中
-
取得跟當前view相關聯的圖形上下文
-
繪製相應的圖形內容
-
利用圖形上下文將繪製的所有內容渲染顯示到view上面
3、爲什麼要在 drawRect 裏面繪圖
只有在這個方法裏面才能獲取到跟 View 的 layer 相關聯的圖形上下文
當這個View要顯示的時候纔會調用drawRect繪製圖形
注意:rect是當前控件的bounds
畫線
1、步驟:
-
獲取圖形上下文
-
描述路徑
-
把路徑添加到上下文
-
渲染上下文
2、直線
方式1:(最原始的繪圖方式)
// 1.獲取圖形上下文 // 目前我們所用的上下文都是以UIGraphics // CGContextRef Ref:引用 CG:目前使用到的類型和函數 一般都是CG開頭 CoreGraphics CGContextRef ctx = UIGraphicsGetCurrentContext(); // 2.描述路徑 // 創建路徑 CGMutablePathRef path = CGPathCreateMutable(); // 設置起點 // path:給哪個路徑設置起點 CGPathMoveToPoint(path, NULL, 0, 250); // 添加一根線到某個點 CGPathAddLineToPoint(path, NULL, 250, 0); // 3.把路徑添加到上下文 CGContextAddPath(ctx, path); // 4.渲染上下文 CGContextStrokePath(ctx);
方式2:(原生)
// 獲取上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 描述路徑 // 設置起點 CGContextMoveToPoint(ctx, 0, 0); CGContextAddLineToPoint(ctx, 250, 250); // 渲染上下文 CGContextStrokePath(ctx);
方式3:貝瑟爾路徑
// UIKit已經封裝了一些繪圖的功能 // 貝瑟爾路徑 // 創建路徑 UIBezierPath *path = [UIBezierPath bezierPath]; // 設置起點 [path moveToPoint:CGPointMake(0, 125)]; // 添加一根線到某個點 [path addLineToPoint:CGPointMake(250, 125)]; // 繪製路徑 [path stroke];
3、線的相關操作
原生
// 獲取上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 描述路徑 //起點 CGContextMoveToPoint(ctx, 50, 50); CGContextAddLineToPoint(ctx, 100, 50); // 設置起點 CGContextMoveToPoint(ctx, 80, 60); // 默認下一根線的起點就是上一根線終點 CGContextAddLineToPoint(ctx, 100, 200); // 設置繪圖狀態,一定要在渲染之前 // 顏色 [[UIColor redColor] setStroke]; // 線寬 CGContextSetLineWidth(ctx, 5); // 設置連接樣式 CGContextSetLineJoin(ctx, kCGLineJoinBevel); // 設置頂角樣式 CGContextSetLineCap(ctx, kCGLineCapRound); // 渲染上下文 CGContextStrokePath(ctx);
貝瑟爾路徑
UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(50, 50)]; [path addLineToPoint:CGPointMake(200, 200)]; // 線寬 path.lineWidth = 10; // 顏色 [[UIColor redColor] set]; [path stroke]; UIBezierPath *path1 = [UIBezierPath bezierPath]; [path1 moveToPoint:CGPointMake(0, 0)]; [path1 addLineToPoint:CGPointMake(30, 60)]; [[UIColor greenColor] set]; path1.lineWidth = 3; [path1 stroke];
比較:
從代碼中可以看出,原生的線操作只能將線繪製爲一種樣式,但是貝瑟爾路徑的對線的操作可以根據路徑的不同來繪製不同樣式的線條
3、曲線
方式1(原生)
// 原生繪製方法 // 獲取上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); // 描述路徑 // 設置起點 CGContextMoveToPoint(ctx, 150, 50); // CGContextAddQuadCurveToPoint(CGContextRef cg_nullable c, CGFloat cpx, CGFloat cpy, CGFloat x, CGFloat y) // cpx:控制點的x // cpy:控制點的y // x, y 爲線結束的點的座標 CGContextAddQuadCurveToPoint(ctx, 50, 50, 50, 150); // 渲染上下文 CGContextStrokePath(ctx);
方式2(貝瑟爾路徑)
// 圓弧 // + (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise; // Center:圓心 // radius:半徑 // startAngle:開始角度 // endAngle:結束角度 // clockwise:YES:順時針 NO:逆時針 CGPoint center = CGPointMake(125, 125); UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:M_PI_2 clockwise:YES]; [path stroke];
4、扇形
未填充
// 扇形 CGPoint center = CGPointMake(125, 125); UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:M_PI_2 clockwise:YES]; // 添加一根線到圓心 [path addLineToPoint:center]; // 封閉路徑,關閉路徑:從路徑的終點到起點 [path closePath]; [path stroke];
代碼效果圖:
填充
// 扇形 CGPoint center = CGPointMake(125, 125); UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:M_PI_2 clockwise:YES]; // 添加一根線到圓心 [path addLineToPoint:center]; // 填充:必須是一個完整的封閉路徑,默認就會自動關閉路徑 [path fill];
代碼效果圖:
5、圓角矩形
// 圓角矩形 // + (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius; // cornerRadius:圓角的弧度,當值爲邊長的一半時,畫出來的圖像爲圓形 UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(20, 20, 200, 200) cornerRadius:50]; [path stroke]; // 填充:必須是一個完整的封閉路徑,默認就會自動關閉路徑 // [path fill];
代碼效果圖:
相關操作同貝塞爾路徑的相關操作類似,大家可以試試,對以上內容有什麼建議的可以直接聯繫我,O(∩_∩)O謝謝!