Quartz 2D愕难。是 iOS 和 Mac OS X 環(huán)境下的2D繪圖引擎早龟。Quartz 2D 也被稱為 Core Graphics惫霸,縮寫前綴為CG,Quartz 2D 與 Quartz Compositor 統(tǒng)稱為 Quartz葱弟,Quartz 原本是 Mac OS X 的 Darwin 核心之上的繪圖技術(shù)壹店。它的 API 接口都是基于 C 的。
1.繪制原理
擺事實芝加,講道理硅卢。在 iOS 中,所有的繪制都離不開 UIView 藏杖,繪制都發(fā)生在 UIView 對象區(qū)域內(nèi)将塑。在繪制發(fā)生的時候,如果是使用的系統(tǒng)提供的視圖蝌麸,則繪制工作會自動發(fā)生点寥。若不是,則我們需要重寫 drawRect:
方法来吩,在此方法中提供相應(yīng)的繪制代碼敢辩。
2.繪制周期
通常我們會設(shè)置一個標志,在每一輪的事件中掃描標志弟疆,看是否需要重新繪制戚长,如果需要我們則調(diào)用 drawRect:
方法進行繪制。于是我們除了 drawRect:
怠苔,還有 setNeedsDisplay
和 setNeedsDisplayInRect:
方法供我們使用同廉。他們分別的作用如下:
setNeedsDisplay
:設(shè)置整個視圖重新繪制。
setNeedsDisplayInRect:
:設(shè)置部分區(qū)域的視圖重新繪制柑司。
3.繪制 - Quartz 圖形上下文
Quartz 圖形上下文是包含繪制系統(tǒng)執(zhí)行后迫肖,繪制命令所需要的信息,定義了各種基本的繪制參數(shù)帜羊,比如繪制使用的顏色咒程、裁剪區(qū)域、線段的寬度及風(fēng)格信息讼育、文體信息帐姻、合成選項以及幾個其他信息。
在調(diào)用 drawRect:
方法之前奶段,視圖對象會自動配置其繪制環(huán)境使代碼能夠立即執(zhí)行進行繪制饥瓷。作為這些配置的一部分,UIView 對象會為當前繪制環(huán)境創(chuàng)建一個圖形上下文(對應(yīng)于 CGContextRef 封裝類型)痹籍。我們可以在 drawRect:
方法中通過 UIGraphicsGetCurrentContext()
來獲取和訪問圖形上下問對象呢铆,再對當前的圖形進行定制的繪制。
4.繪制 - 具體實現(xiàn)
4.1 繪制一條直線
#import "BJView.h"
@implementation BJView
- (void)drawRect:(CGRect)rect {
//獲取圖形上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//設(shè)置線條顏色
CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
//設(shè)置線條寬度
CGContextSetLineWidth(context, 2.f);
//設(shè)置線條起點和終點的樣式
CGContextSetLineCap(context, kCGLineCapRound);
//設(shè)置線條的轉(zhuǎn)角的樣式
CGContextSetLineJoin(context, kCGLineJoinRound);
// 繪制線方式 1
// CGContextMoveToPoint(context, 100, 120);
// CGContextAddLineToPoint(context, 150, 120);
// 繪制線方式 2
CGPoint apoint[2];
apoint[0] = CGPointMake(100, 120);
apoint[1] = CGPointMake(150, 120);
CGContextAddLines(context, apoint, 2);
//是否閉合路徑
// CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke);
}
@end
效果:
4.2 繪制一條折線(閉合且填充內(nèi)容,相當于三角形)
#import "BJView.h"
@implementation BJView
- (void)drawRect:(CGRect)rect {
//獲取圖形上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//設(shè)置邊框顏色
CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
//設(shè)置填充顏色
CGContextSetRGBFillColor(context, 0, 1, 0, 1);
//設(shè)置線條寬度
CGContextSetLineWidth(context, 2.f);
//設(shè)置線條起點和終點的樣式
CGContextSetLineCap(context, kCGLineCapRound);
//設(shè)置線條的轉(zhuǎn)角的樣式
CGContextSetLineJoin(context, kCGLineJoinRound);
// 繪制線方式 1
// CGContextMoveToPoint(context, 100, 120);
// CGContextAddLineToPoint(context, 150, 120);
// CGContextAddLineToPoint(context, 150, 180);
// 繪制線方式 2
CGPoint apoint[3];
apoint[0] = CGPointMake(100, 120);
apoint[1] = CGPointMake(150, 120);
apoint[2] = CGPointMake(150, 180);
CGContextAddLines(context, apoint, 3);
//閉合路徑
CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke);
}
@end
效果:
4.3 繪制一個矩形
#import "BJView.h"
@implementation BJView
- (void)drawRect:(CGRect)rect {
//獲取圖形上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//設(shè)置邊框顏色
CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
//設(shè)置填充顏色
CGContextSetRGBFillColor(context, 0, 1, 0, 1);
//設(shè)置線條寬度
CGContextSetLineWidth(context, 2.f);
//設(shè)置線條起點和終點的樣式
// CGContextSetLineCap(context, kCGLineCapRound);
//設(shè)置線條的轉(zhuǎn)角的樣式
CGContextSetLineJoin(context, kCGLineJoinRound);
// 通過繪制線的方式 1
// CGContextMoveToPoint(context, 100, 100);
// CGContextAddLineToPoint(context, 150, 100);
// CGContextAddLineToPoint(context, 150, 150);
// CGContextAddLineToPoint(context, 100, 150);
// 通過繪制線的方式 2
// CGPoint apoint[4];
// apoint[0] = CGPointMake(100, 100);
// apoint[1] = CGPointMake(150, 100);
// apoint[2] = CGPointMake(150, 150);
// apoint[3] = CGPointMake(100, 150);
// CGContextAddLines(context, apoint, 4);
// 繪制矩形方法
CGContextAddRect(context, CGRectMake(100, 100, 50, 50));
//閉合路徑
// CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke);
}
@end
效果:
4.4 繪制一個圓(橢圓的特殊形態(tài))
#import "BJView.h"
@implementation BJView
- (void)drawRect:(CGRect)rect {
//獲取圖形上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//設(shè)置邊框顏色
CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
//設(shè)置填充顏色
CGContextSetRGBFillColor(context, 0, 1, 0, 1);
//設(shè)置線條寬度
CGContextSetLineWidth(context, 2.f);
//設(shè)置線條起點和終點的樣式
// CGContextSetLineCap(context, kCGLineCapRound);
//設(shè)置線條的轉(zhuǎn)角的樣式
// CGContextSetLineJoin(context, kCGLineJoinRound);
// 繪制圓方法(其實所繪制的圓為所繪制用的Rect的矩形的內(nèi)切圓蹲缠,當寬度等于高度時棺克,即為正圓)
CGContextAddEllipseInRect(context, CGRectMake(100, 100, 200, 100));
//閉合路徑
// CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke);
}
@end
效果:
4.5 繪制一段圓挥贫狻(閉合且填充內(nèi)容,相當于扇形)
#import "BJView.h"
#define arc(angle) ((angle)*(M_PI/180.0))
@implementation BJView
- (void)drawRect:(CGRect)rect {
//獲取圖形上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//設(shè)置邊框顏色
CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
//設(shè)置填充顏色
CGContextSetRGBFillColor(context, 0, 1, 0, 1);
//設(shè)置線條寬度
CGContextSetLineWidth(context, 2.f);
//設(shè)置線條起點和終點的樣式
CGContextSetLineCap(context, kCGLineCapRound);
//設(shè)置線條的轉(zhuǎn)角的樣式
// CGContextSetLineJoin(context, kCGLineJoinRound);
// 繪制圓弧方法1 (參數(shù)由左至右分別是,圖形上下文娜谊、圓心x确买、圓心y、半徑纱皆、起始弧度湾趾、結(jié)束弧度、圓弧伸展的方向(0為順時針派草,1為逆時針))
CGContextAddArc(context, 150, 100, 100, arc(0), arc(160), 0);
// 繪制圓弧方法2搀缠,由起始點、結(jié)束點分別與中間節(jié)點連線近迁,同時以半徑切過這兩邊則確定一段圓弧(不建議使用艺普,因為理解不方便)
// CGContextMoveToPoint(context, 100, 100);
// CGContextAddArcToPoint(context, 150, 100, 150, 150, 50);
//閉合路徑
CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke);
}
@end
效果:
4.6 繪制一段文字
#import "BJView.h"
#define arc(angle) ((angle)*(M_PI/180.0))
@implementation BJView
- (void)drawRect:(CGRect)rect {
NSString * str = @"BradleyJohnson";
NSMutableDictionary * attributes = [NSMutableDictionary dictionary];
attributes[NSFontAttributeName] = [UIFont systemFontOfSize:20]; attributes[NSForegroundColorAttributeName] = [UIColor purpleColor];
attributes[NSBackgroundColorAttributeName] = [UIColor whiteColor];
[str drawInRect:CGRectMake(100, 100, 200, 30) withAttributes:attributes];
}
@end
效果:
4.6 繪制一張圖片
#import "BJView.h"
@implementation BJView
- (void)drawRect:(CGRect)rect {
UIImage * img = [UIImage imageNamed:@"bradleyJohnson.jpg"];
// 在指定的范圍內(nèi)繪制圖片,有可能引起圖片拉伸
[img drawInRect:rect];
}
@end
效果:
5.繪制 - 貝塞爾曲線繪制
貝塞爾曲線鉴竭,使用UIBezierPath類可以創(chuàng)建基于矢量的路徑衷敌,這個類在UIKit中。它基本可以實現(xiàn)我們上面利用圖形上下文做到的功能拓瞪。
例如:
#import "BJView.h"
@implementation BJView
- (void)drawRect:(CGRect)rect {
[[UIColor redColor] setStroke];
UIBezierPath * path = [UIBezierPath bezierPath];
path.lineWidth = 2.0;
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinBevel;
[path moveToPoint:CGPointMake(10, 20)];
[path addLineToPoint:CGPointMake(50, 20)];
[path closePath];
[path stroke];
}
@end
這就可以輕易的繪制出一條直線,效果如圖:
同樣的助琐,我們也可以輕易的繪制出三角形祭埂、矩形、橢圓(圓)兵钮、圓弧如下:
#import "BJView.h"
#define arc(angle) ((angle)*(M_PI/180.0))
@implementation BJView
- (void)drawRect:(CGRect)rect {
/* 三角形 */
[[UIColor redColor] setStroke];
UIBezierPath * path = [UIBezierPath bezierPath];
path.lineWidth = 2.0;
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinBevel;
[path moveToPoint:CGPointMake(10, 20)];
[path addLineToPoint:CGPointMake(50, 20)];
[path addLineToPoint:CGPointMake(50, 60)];
[path closePath];
[path stroke];
/* 圓弧 */
[[UIColor redColor] setStroke];
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100,100) radius:100 startAngle:0 endAngle:arc(135) clockwise:YES];
[path stroke];
/* 矩形 */
[[UIColor redColor] setStroke];
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(20, 20, 100, 100)];
[path stroke];
/* 橢圓(圓) */
[[UIColor redColor] setStroke];
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(20, 20, 100, 100)];
[path stroke];
}
@end
當然最經(jīng)典的就是蛆橡,我們可以繪制二次和三次的貝塞爾曲線:
#import "BJView.h"
@implementation BJView
- (void)drawRect:(CGRect)rect {
[[UIColor redColor] setStroke];
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(20, 100)];
// 繪制二次貝塞爾曲線
// [path addQuadCurveToPoint:CGPointMake(120, 100) controlPoint:CGPointMake(70, 150)];
// 繪制三次貝塞爾曲線
[path addCurveToPoint:CGPointMake(120, 100) controlPoint1:CGPointMake(45, 150) controlPoint2:CGPointMake(95, 50)];
[path stroke];
}
@end
效果如下:
如果你想要看到源碼,可以到我的github上下載使用:Demo掘譬。
如果你喜歡我的文章泰演,請不要吝嗇你的喜歡和關(guān)注,這是我的個人博客.