iOS開發——Core Graphics繪圖
我們在搭建UI介面時,有很多時候,我們會用到iOS自帶的繪圖功能來完成一些介面的效果,很常用也很方便。今天我們在這裡就一起討論一下iOS的繪圖功能。
CoreGraphics也稱為Quartz 2D 是UIKit下的主要繪圖系統,頻繁的用於繪製自定義檢視。Core Graphics是高度整合於UIView和其他UIKit部分的。Core Graphics資料結構和函式可以通過字首CG來識別。
檢視可以通過子檢視、圖層或實現drawRect:方法來表現內容,如果說實現了drawRect:方法,那麼最好就不要混用其他方法了,如圖層和子檢視。自定義繪圖大部分是由UIKit或者Core Graphics來實現的。
由於畫素是依賴於目標的,所以2D繪圖並不能操作單獨的畫素,我們可以從上下文(Context)讀取它。
繪圖就好比在畫布上拿著畫筆機械的進行畫畫,通過制定不同的引數來進行不同的繪製。
iOS常見的圖形繪製
- 畫線
- 畫圓、圓弧、貝塞爾曲線
- 畫矩形、橢圓形、多邊形
- 繪製圖片
- 繪製文字
iOS繪圖基礎
在繪圖之前,我們先來了解一下幾個基本的概念
context:上下文,ios繪圖的方法都需要傳一個上下文context,這個context在重寫uiview的drawRect的方法裡呼叫UIGraphicsGetCurrentContext()獲取
path:路徑,ios繪圖可以想象為你拿著一支筆去畫圖,畫幾條線或幾個點從而形成一個路徑,之後可以利用理解去填色或者描邊
stroke,fill 描邊和填充,每個路徑都需要填充或者描邊後才能在檢視中看見,他們都各自有很多樣式可以設定,常見的有顏色、粗細、漸變,連線樣式等等。
畫圖可以使用預設路徑畫,或者單獨建立path畫圖,對應畫圖的api並不完全相同,是兩組名稱相似的api,兩組api常用的方法如下
CGContextMoveToPoint //設定起點
CGContextClosePath //連線起點和當前點
CGPathCreateMutable //類似於 CGContextBeginPath
CGPathMoveToPoint //類似於 CGContextMoveToPoint
CGPathAddLineToPoint //類似於 CGContextAddLineToPoint
CGPathAddCurveToPoint //類似於 CGContextAddCurveToPoint
CGPathAddEllipseInRect //類似於 CGContextAddEllipseInRect
CGPathAddArc //類似於 CGContextAddArc
CGPathAddRect //類似於 CGContextAddRect
CGPathCloseSubpath //類似於 CGContextClosePath
CGContextAddPath //函式把一個路徑新增到graphics
畫圖步驟
- 獲取context
- 設定Path
- 填充或描邊路徑
關於填充顏色 有三種方式
- 填充筆觸,就是隻給路徑描邊
- 根據路徑填充顏色
- 填充筆觸和顏色
填充顏色也分為非零繞數規則和奇偶規則,這個概念比較複雜難以解釋,大家可以百度看看或者畫幾個圖試試就明白。
CGContextStrokePath(ctx); //描出路徑
CGContextFillPath(ctx) //使用非零繞數規則填充當前路徑
CGContextDrawPath //兩個引數決定填充規則,kCGPathFill表示用非零繞數規則,kCGPathEOFill表示用奇偶規則,kCGPathFillStroke表示填充,kCGPathEOFillStroke表示描線,不是填充
CGContextEOFillPath //使用奇偶規則填充當前路徑
CGContextFillRect //填充指定的矩形
CGContextFillRects //填充指定的一些矩形
CGContextFillEllipseInRect //填充指定矩形中的橢圓
常見的圖形繪製
準備工作
- 新建一個檔案,繼承UIView
- 重寫
-(void)drawRect:(CGRect)rect
方法
-(void)drawRect:(CGRect)rect{
[super drawRect:rect];
//獲取ctx
CGContextRef ctx = UIGraphicsGetCurrentContext();
//設定畫圖相關樣式引數
//設定筆觸顏色
CGContextSetStrokeColorWithColor(ctx, [UIColor blackColor].CGColor);//設定顏色有很多方法,我覺得這個方法最好用
//設定筆觸寬度
CGContextSetLineWidth(ctx, 2);
//設定填充色
CGContextSetFillColorWithColor(ctx, [UIColor purpleColor].CGColor);
//設定拐點樣式
// enum CGLineJoin {
// kCGLineJoinMiter, //尖的,斜接
// kCGLineJoinRound, //圓
// kCGLineJoinBevel //斜面
// };
CGContextSetLineJoin(ctx, kCGLineJoinRound);
//Line cap 線的兩端的樣式
// enum CGLineCap {
// kCGLineCapButt,
// kCGLineCapRound,
// kCGLineCapSquare
// };
CGContextSetLineCap(ctx, kCGLineCapRound);
//虛線線條樣式
//CGFloat lengths[] = {10,10};
//畫線
[self drawLine:ctx];
//畫圓、圓弧
[self drawCircle:ctx];
//畫矩形,畫橢圓,多邊形
[self drawShape:ctx];
//畫圖片
[self drawPicture:ctx];
//畫文字
[self drawText:ctx];
}
畫線
第一個方法我寫的比較詳細,寫了使用path的方式和直接畫線的方式。推薦使用path的方式畫線。 另外,第一個方法也寫了移動筆觸畫線和用點集合畫線。後面方法只會涉及其中一種,因為方法都比較類似。
//畫線
-(void)drawLine:(CGContextRef)ctx{
//畫一條簡單的線
CGPoint points1[] = {CGPointMake(10, 30),CGPointMake(300, 30)};
CGContextAddLines(ctx,points1, 2);
//畫線方法1,使用CGContextAddLineToPoint畫線,需要先設定一個起始點
//設定起始點
CGContextMoveToPoint(ctx, 50, 50);
//新增一個點
CGContextAddLineToPoint(ctx, 100,50);
//在新增一個點,變成折線
CGContextAddLineToPoint(ctx, 150, 100);
//畫線方法2
//構造線路徑的點陣列
CGPoint points2[] = {CGPointMake(60, 60),CGPointMake(80, 120),CGPointMake(20, 300)};
CGContextAddLines(ctx,points2, 3);
//利用路徑去畫一組點(推薦使用路徑的方式,雖然多了幾行程式碼,但是邏輯更清晰了)
//第一個路徑
CGMutablePathRef path1 = CGPathCreateMutable();
CGPathMoveToPoint(path1, &CGAffineTransformIdentity, 0, 200);
//CGAffineTransformIdentity 類似於初始化一些引數
CGPathAddLineToPoint(path1, &CGAffineTransformIdentity, 100, 250);
CGPathAddLineToPoint(path1, &CGAffineTransformIdentity, 310, 210);
//路徑1加入context
CGContextAddPath(ctx, path1);
//path同樣有方法CGPathAddLines(),和CGContextAddLines()差不多使用者,可以自己試下
//描出筆觸
CGContextStrokePath(ctx);
}
畫矩形、橢圓形、多邊形
//畫矩形,畫橢圓,多邊形
-(void)drawSharp:(CGContextRef)ctx{
CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
//畫橢圓,如果長寬相等就是圓
CGContextAddEllipseInRect(ctx, CGRectMake(0, 250, 50, 50));
//畫矩形,長寬相等就是正方形
CGContextAddRect(ctx, CGRectMake(70, 250, 50, 50));
//畫多邊形,多邊形是通過path完成的
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, &CGAffineTransformIdentity, 120, 250);
CGPathAddLineToPoint(path, &CGAffineTransformIdentity, 200, 250);
CGPathAddLineToPoint(path, &CGAffineTransformIdentity, 180, 300);
CGPathCloseSubpath(path);
CGContextAddPath(ctx, path);
//填充
CGContextFillPath(ctx);
}
畫圖
//畫圖片
-(void)drawPicture:(CGContextRef)context{
/*圖片*/
UIImage *image = [UIImage imageNamed:@"head.jpeg"];
[image drawInRect:CGRectMake(10, 300, 100, 100)];//在座標中畫出圖片
}
畫文字
//畫文字
-(void)drawText:(CGContextRef)ctx{
//文字樣式
UIFont *font = [UIFont systemFontOfSize:18];
NSDictionary *dict = @{NSFontAttributeName:font,
NSForegroundColorAttributeName:[UIColor whiteColor]};
[@"hello world" drawInRect:CGRectMake(120 , 350, 500, 50) withAttributes:dict];
}
畫圓、圓弧、貝塞爾曲線
** 畫圓和圓弧是一回事,只是起點和重點位置不同,畫圓畫弧線主要依賴於這幾個方法 CGContextAddArc
, CGContextAddArcToPoint
, CGContextAddCurveToPoint
, CGContextAddQuadCurveToPoint
後面兩個方法是貝塞爾二次曲線和三次曲線 **
//畫圓、圓弧
-(void)drawCircle:(CGContextRef)ctx{
CGContextSetStrokeColorWithColor(ctx, [UIColor purpleColor].CGColor);
/* 繪製路徑 方法一
void CGContextAddArc (
CGContextRef c,
CGFloat x, //圓心的x座標
CGFloat y, //圓心的x座標
CGFloat radius, //圓的半徑
CGFloat startAngle, //開始弧度
CGFloat endAngle, //結束弧度
int clockwise //0表示順時針,1表示逆時針
);
*/
//圓
CGContextAddArc (ctx, 100, 100, 50, 0, M_PI* 2 , 0);
CGContextStrokePath(ctx);
//半圓
CGContextAddArc (ctx, 100, 200, 50, 0, M_PI*2, 0);
CGContextStrokePath(ctx);
//繪製路徑 方法二,這方法適合繪製弧度 ,端點p1和p2是弧線的控制點,類似photeshop中鋼筆工具控制曲線,還不明白請去了解貝塞爾曲線
// void CGContextAddArcToPoint(
// CGContextRef c,
// CGFloat x1, //端點1的x座標
// CGFloat y1, //端點1的y座標
// CGFloat x2, //端點2的x座標
// CGFloat y2, //端點2的y座標
// CGFloat radius //半徑
// );
//1/4弧度 * 4
CGContextMoveToPoint(ctx, 200, 200);
CGContextAddArcToPoint(ctx, 200, 100,300, 100, 100);
CGContextAddArcToPoint(ctx, 400, 100,400, 200, 100);
CGContextAddArcToPoint(ctx, 400, 300,300, 300, 100);
CGContextAddArcToPoint(ctx, 200, 300,200, 200, 100);
CGContextStrokePath(ctx);
//貝塞爾曲線
CGContextSetStrokeColorWithColor(ctx, [UIColor orangeColor].CGColor);
//三次曲線函式
//void CGContextAddCurveToPoint (
// CGContextRef c,
// CGFloat cp1x, //控制點1 x座標
// CGFloat cp1y, //控制點1 y座標
// CGFloat cp2x, //控制點2 x座標
// CGFloat cp2y, //控制點2 y座標
// CGFloat x, //直線的終點 x座標
// CGFloat y //直線的終點 y座標
// );
CGContextMoveToPoint(ctx, 200, 200);
CGContextAddCurveToPoint(ctx, 200, 0, 300, 200, 400, 100);
CGContextStrokePath(ctx);
//三次曲線可以畫圓弧,比如這裡畫一條之前用CGContextAddArcToPoint構成的圓弧
CGContextMoveToPoint(ctx, 200, 200);
CGContextAddCurveToPoint(ctx, 200, 100, 300, 100, 300 ,100);
CGContextStrokePath(ctx);
//二次曲線函式
//void CGContextAddQuadCurveToPoint (
// CGContextRef c,
// CGFloat cpx, //控制點 x座標
// CGFloat cpy, //控制點 y座標
// CGFloat x, //直線的終點 x座標
// CGFloat y //直線的終點 y座標
// );
CGContextMoveToPoint(ctx, 100, 100);
CGContextAddQuadCurveToPoint(ctx, 200, 0, 300, 150);
CGContextStrokePath(ctx);
}
因為程式碼可以直接拷貝下去用,也就不上傳到Github上的demo裡了。
相關文章
- iOS開發基礎110-Core Graphics應用場景iOS
- iOS圖形處理概論:OpenGL ES,Metal,Core Graphics,Core Image,GPUImage,OpenCV等iOSGPUUIOpenCV
- CorelDRAW Graphics Suite 2022 Mac(專業向量繪圖軟體)UIMac繪圖
- iOS開發UI篇--iOS動畫(Core Animation)總結iOSUI動畫
- iOS開發基礎135-Core DataiOS
- iOS開發-圖片UIImageiOSUI
- dotnet 控制檯 使用 Microsoft.Maui.Graphics 配合 Skia 進行繪圖入門ROSUI繪圖
- iOS股票K線圖、分時圖繪製iOS
- iOS開發_繪製圓角矩形虛線環iOS
- 玩轉iOS開發:7.《Core Animation》Implicit AnimationsiOS
- 【iOS 開發】iOS 10.3 如何更換 app 圖示iOSAPP
- iOS使用Charts框架繪製折線圖iOS框架
- iOS開發圖片格式選擇iOS
- C++ Qt開發:Charts繪圖元件概述C++QT繪圖元件
- Android OpenGL ES 開發(二):繪製圖形Android
- 玩轉iOS開發:6.《Core Animation》CALayer的Specialized LayersiOSZed
- 音視訊開發指南:圖片的繪製
- C++ Qt開發:Charts折線圖繪製詳解C++QT
- iOS 開發iOS
- Android 開發:使用繪製基金圖表類(帶快取的圖表類)Android快取
- iOS 重繪之drawRectiOS
- iOS UI繪製原理iOSUI
- iOS 繪製圓角iOS
- C++ Qt開發:Charts繪製各類圖表詳解C++QT
- WPF開發隨筆收錄-心電圖曲線繪製
- 玩轉iOS開發:iOS中的NSOperation開發(一)iOS
- CorelDRAW Graphics Suite 2021.5 Mac(圖形設計軟體)UIMac
- iOS開發-MVCiOSMVC
- iOS開發- RunLoopiOSOOP
- iOS開發-UIButtoniOSUI
- iOS開發:UIAlertViewiOSUIView
- iOS 開發薪水iOS
- 百度地圖開發-繪製點線提示框 07地圖
- 【Android繪圖】繪圖之基礎篇(一)Android繪圖
- 《iOS 開發輔助篇》使用OmniGraffle匯出Xcode類圖iOSXCode
- iOS開發UI篇--一個支援圖文混排的ActionSheetiOSUI
- iOS開發-新建相簿並儲存圖片到該相簿iOS
- ?????iOS圖表框架AAChartKit—強大、精美、易用的開源iOS圖表iOS框架
- PLT繪圖繪圖