轉(zhuǎn)自:iOS繪圖—— UIBezierPath 和 Core Graphics
繪圖進(jìn)階請(qǐng)參考:繪圖
前言
iOS系統(tǒng)本身提供了兩套繪圖的框架,即UIBezierPath 和 Core Graphics。而前者所屬UIKit,其實(shí)是對(duì)Core Graphics框架關(guān)于path的進(jìn)一步封裝,所以使用起來(lái)比較簡(jiǎn)單。但是畢竟Core Graphics更接近底層,所以它更加強(qiáng)大。
UIBezierPath
可以創(chuàng)建基于矢量的路徑,例如橢圓或者矩形,或者有多個(gè)直線和曲線段組成的形狀。
使用UIBezierPath,你只能在當(dāng)前上下文中繪圖,所以如果你當(dāng)前處于UIGraphicsBeginImageContextWithOptions函數(shù)或drawRect:方法中,你就可以直接使用UIKit提供的方法進(jìn)行繪圖。如果你持有一個(gè)context:參數(shù),那么使用UIKit提供的方法之前,必須將該上下文參數(shù)轉(zhuǎn)化為當(dāng)前上下文。幸運(yùn)的是,調(diào)用UIGraphicsPushContext 函數(shù)可以方便的將context:參數(shù)轉(zhuǎn)化為當(dāng)前上下文,記住最后別忘了調(diào)用UIGraphicsPopContext函數(shù)恢復(fù)上下文環(huán)境。
簡(jiǎn)言之:我們一般使用UIBezierPath都是在重寫的drawRecrt方法這種情形。其繪圖的步驟是這樣的:
- 重寫drawRect方法。但不需要我們自己獲取當(dāng)前上下文context;
- 創(chuàng)建相應(yīng)圖形的UIBezierPath對(duì)象,并設(shè)置一些修飾屬性;
- 渲染,完成繪制。
// 1.重寫drawRect方法
- (void)drawRect:(CGRect)rect {
// 2.創(chuàng)建圖形相應(yīng)的UIBezierPath對(duì)象
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(20, 20, 100, 50)];
// 設(shè)置一些修飾屬性
path.lineWidth = 28.0;
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinRound;
UIColor *color = [UIColor colorWithRed:0 green:0 blue:0.7 alpha:1];
[color set];
// 4.渲染,完成繪制
[path stroke];
}
效果如下:

Core Graphics
這是一個(gè)繪圖專用的API族,它經(jīng)常被稱為QuartZ或QuartZ 2D。Core Graphics是iOS上所有繪圖功能的基石,包括UIKit。
要搞清楚Core Graphics就要搞清楚下面幾個(gè)問(wèn)題:
1. 繪圖需要 CGContextRef
CGContextRef即圖形上下文。可以這么理解,我們繪圖是需要一個(gè)載體或者說(shuō)輸出目標(biāo),它用來(lái)顯示繪圖信息,并且決定繪制的東西輸出到哪個(gè)地方??梢孕蜗蟮谋扔?code>context就像一個(gè)“畫(huà)板”,我們得把圖形繪制到這個(gè)畫(huà)板上。所以,繪圖必須要先有context。
2. 怎么拿到context?
第一種方法是利用cocoa為你生成的圖形上下文。當(dāng)你子類化了一個(gè)UIView并實(shí)現(xiàn)了自己的drawRect:方法后,一旦drawRect:方法被調(diào)用,Cocoa就會(huì)為你創(chuàng)建一個(gè)圖形上下文,此時(shí)你對(duì)圖形上下文的所有繪圖操作都會(huì)顯示在UIView上。
第二種方法就是創(chuàng)建一個(gè)圖片類型的上下文。調(diào)用UIGraphicsBeginImageContextWithOptions函數(shù)就可獲得用來(lái)處理圖片的圖形上下文。利用該上下文,你就可以在其上進(jìn)行繪圖,并生成圖片。調(diào)用UIGraphicsGetImageFromCurrentImageContext函數(shù)可從當(dāng)前上下文中獲取一個(gè)UIImage對(duì)象。記住在你所有的繪圖操作后別忘了調(diào)用UIGraphicsEndImageContext函數(shù)關(guān)閉圖形上下文。
簡(jiǎn)言之:
- 重寫UIView的drawRect方法,在該方法里便可得到context;
- 調(diào)用UIGraphicsBeginImageContextWithOptions方法得到context;
3. 注意
并不是說(shuō)一提到繪圖,就一定得重寫drawRect方法,只是因?yàn)橥ǔG闆r下我們一般采用在drawRect方法里獲取context這種方式。
4. drawRect方法什么時(shí)候觸發(fā)
- 1.當(dāng)view第一次顯示到屏幕上時(shí);
- 2.當(dāng)調(diào)用view的
setNeedsDisplay或者setNeedsDisplayInRect:方法時(shí)。
步驟:
- 1.先在drawRect方法中獲得上下文context;
- 2.繪制圖形(線,圖形,圖片等);
- 3.設(shè)置一些修飾屬性;
- 4.渲染到上下文,完成繪圖。
- (void)drawRect:(CGRect)rect {
// 1.獲取上下文
CGContextRef context = UIGraphicsGetCurrentContext();
// --------------------------實(shí)心圓
// 2.畫(huà)圖
CGContextAddEllipseInRect(context, CGRectMake(10, 10, 50, 50));
[[UIColor greenColor] set];
// 3.渲染
CGContextFillPath(context);
// --------------------------空心圓
CGContextAddEllipseInRect(context, CGRectMake(70, 10, 50, 50));
[[UIColor redColor] set];
CGContextStrokePath(context);
// --------------------------橢圓
//畫(huà)橢圓和畫(huà)圓方法一樣,橢圓只是設(shè)置不同的長(zhǎng)寬
CGContextAddEllipseInRect(context, CGRectMake(130, 10, 100, 50));
[[UIColor purpleColor] set];
CGContextFillPath(context);
// --------------------------直線
CGContextMoveToPoint(context, 20, 80); // 起點(diǎn)
CGContextAddLineToPoint(context, self.frame.size.width-10, 80); //終點(diǎn)
// CGContextSetRGBStrokeColor(ctx, 0, 1.0, 0, 1.0); // 顏色
[[UIColor redColor] set]; // 兩種設(shè)置顏色的方式都可以
CGContextSetLineWidth(context, 2.0f); // 線的寬度
CGContextSetLineCap(context, kCGLineCapRound); // 起點(diǎn)和重點(diǎn)圓角
CGContextSetLineJoin(context, kCGLineJoinRound); // 轉(zhuǎn)角圓角
CGContextStrokePath(context); // 渲染(直線只能繪制空心的,不能調(diào)用CGContextFillPath(ctx);)
// --------------------------三角形
CGContextMoveToPoint(context, 10, 150); // 第一個(gè)點(diǎn)
CGContextAddLineToPoint(context, 60, 100); // 第二個(gè)點(diǎn)
CGContextAddLineToPoint(context, 100, 150); // 第三個(gè)點(diǎn)
[[UIColor purpleColor] set];
CGContextClosePath(context);
CGContextStrokePath(context);
// --------------------------矩形
CGContextAddRect(context, CGRectMake(20, 170, 100, 50));
[[UIColor orangeColor] set];
// CGContextStrokePath(ctx); // 空心
CGContextFillPath(context);
// --------------------------圓弧
CGContextAddArc(context, 200, 170, 50, M_PI, M_PI_4, 0);
CGContextClosePath(context);
CGContextFillPath(context);
// --------------------------文字
NSString *str = @"你在紅樓,我在西游";
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[NSForegroundColorAttributeName] = [UIColor whiteColor]; // 文字顏色
dict[NSFontAttributeName] = [UIFont systemFontOfSize:14]; // 字體
[str drawInRect:CGRectMake(20, 250, 300, 30) withAttributes:dict];
// --------------------------圖片
UIImage *img = [UIImage imageNamed:@"yingmu"];
// [img drawAsPatternInRect:CGRectMake(20, 280, 300, 300)]; // 多個(gè)平鋪
// [img drawAtPoint:CGPointMake(20, 280)]; // 繪制到指定點(diǎn),圖片有多大就顯示多大
[img drawInRect:CGRectMake(20, 280, 80, 80)]; // 拉伸
}