本文demo下載
ios常見(jiàn)的圖形繪制
- 畫(huà)線(xiàn)
- 畫(huà)圓勇婴、圓弧
- 畫(huà)矩形,畫(huà)橢圓,多邊形
- 畫(huà)圖片
- 畫(huà)文字
1:ios繪圖基礎(chǔ)
幾個(gè)基本的概念
context:上下文傍菇,ios繪圖的方法都需要傳一個(gè)上下文context絮重,這個(gè)context在重寫(xiě)uiview的drawRect的方法里調(diào)用UIGraphicsGetCurrentContext()獲取
path:路徑惋啃,ios繪圖可以想象為你拿著一支筆去畫(huà)圖碴开,畫(huà)幾條線(xiàn)或幾個(gè)點(diǎn)從而形成一個(gè)路徑毅该,之后可以利用理解去填色或者描邊
stroke,fill 描邊和填充博秫,每個(gè)路徑都需要填充或者描邊后才能在視圖中看見(jiàn)潦牛,他們都各自有很多樣式可以設(shè)置,常見(jiàn)的有顏色挡育、粗細(xì)巴碗、漸變,連接樣式等等即寒。
畫(huà)圖可以使用默認(rèn)路徑畫(huà)橡淆,或者單獨(dú)創(chuàng)建path畫(huà)圖召噩,對(duì)應(yīng)畫(huà)圖的api并不完全相同,是兩組名稱(chēng)相似的api逸爵,兩組pi常用的方法如下
CGContextMoveToPoint設(shè)置起點(diǎn)
CGContextClosePath 連接起點(diǎn)和當(dāng)前點(diǎn)
CGPathCreateMutable 類(lèi)似于 CGContextBeginPath
CGPathMoveToPoint 類(lèi)似于 CGContextMoveToPoint
CGPathAddLineToPoint 類(lèi)似于 CGContextAddLineToPoint
CGPathAddCurveToPoint 類(lèi)似于 CGContextAddCurveToPoint
CGPathAddEllipseInRect 類(lèi)似于 CGContextAddEllipseInRect
CGPathAddArc 類(lèi)似于 CGContextAddArc
CGPathAddRect 類(lèi)似于 CGContextAddRect
CGPathCloseSubpath 類(lèi)似于 CGContextClosePath
CGContextAddPath函數(shù)把一個(gè)路徑添加到graphics
畫(huà)圖步驟 1:獲取context具滴,2:設(shè)置路徑 3:填充或描邊路徑
關(guān)于填充顏色 填充顏色有3種模式,分別是1:填充筆觸师倔,就是只給路徑描邊构韵,2:根據(jù)路徑填充顏色 3:填充筆觸和顏色。填充顏色也分為非零繞數(shù)規(guī)則和奇偶規(guī)則趋艘,這個(gè)概念比較復(fù)雜難以解釋?zhuān)蠹铱梢园俣瓤纯椿蛘呋◣讉€(gè)圖試試就明白疲恢。
CGContextStrokePath(ctx); //描出路徑
CGContextFillPath(ctx) 使用非零繞數(shù)規(guī)則填充當(dāng)前路徑
CGContextDrawPath 兩個(gè)參數(shù)決定填充規(guī)則,kCGPathFill表示用非零繞數(shù)規(guī)則瓷胧,kCGPathEOFill表示用奇偶規(guī)則显拳,kCGPathFillStroke表示填充,kCGPathEOFillStroke表示描線(xiàn)搓萧,不是填充
CGContextEOFillPath 使用奇偶規(guī)則填充當(dāng)前路徑
CGContextFillRect 填充指定的矩形
CGContextFillRects 填充指定的一些矩形
CGContextFillEllipseInRect 填充指定矩形中的橢圓
2:ios常見(jiàn)的圖形繪制
(1)新建一個(gè)文件杂数,繼承UIView
(2)重寫(xiě)-(void)drawRect:(CGRect)rect; 方法
-(void)drawRect:(CGRect)rect{
[super drawRect:rect];
//獲取ctx
CGContextRef ctx = UIGraphicsGetCurrentContext();
//設(shè)置畫(huà)圖相關(guān)樣式參數(shù)
//設(shè)置筆觸顏色
CGContextSetStrokeColorWithColor(ctx, [UIColor blackColor].CGColor);//設(shè)置顏色有很多方法矛绘,我覺(jué)得這個(gè)方法最好用
//設(shè)置筆觸寬度
CGContextSetLineWidth(ctx, 2);
//設(shè)置填充色
CGContextSetFillColorWithColor(ctx, [UIColor purpleColor].CGColor);
//設(shè)置拐點(diǎn)樣式
// enum CGLineJoin {
// kCGLineJoinMiter, //尖的耍休,斜接
// kCGLineJoinRound, //圓
// kCGLineJoinBevel //斜面
// };
CGContextSetLineJoin(ctx, kCGLineJoinRound);
//Line cap 線(xiàn)的兩端的樣式
// enum CGLineCap {
// kCGLineCapButt,
// kCGLineCapRound,
// kCGLineCapSquare
// };
CGContextSetLineCap(ctx, kCGLineCapRound);
//虛線(xiàn)線(xiàn)條樣式
//CGFloat lengths[] = {10,10};
//畫(huà)線(xiàn)
[self drawLine:ctx];
//畫(huà)圓、圓弧
[self drawCircle:ctx];
//畫(huà)矩形,畫(huà)橢圓货矮,多邊形
[self drawShape:ctx];
//畫(huà)圖片
[self drawPicture:ctx];
//畫(huà)文字
[self drawText:ctx];
}
2.1:畫(huà)線(xiàn)
第一個(gè)方法我寫(xiě)的比較詳細(xì)羊精,寫(xiě)了使用path的方式和直接畫(huà)線(xiàn)的方式。推薦使用path的方式畫(huà)線(xiàn)囚玫。 另外喧锦,第一個(gè)方法也寫(xiě)了移動(dòng)筆觸畫(huà)線(xiàn)和用點(diǎn)集合畫(huà)線(xiàn)。后面方法只會(huì)涉及其中一種抓督,因?yàn)榉椒ǘ急容^類(lèi)似燃少。
//畫(huà)線(xiàn)
-(void)drawLine:(CGContextRef)ctx{
//畫(huà)一條簡(jiǎn)單的線(xiàn)
CGPoint points1[] = {CGPointMake(10, 30),CGPointMake(300, 30)};
CGContextAddLines(ctx,points1, 2);
//畫(huà)線(xiàn)方法1,使用CGContextAddLineToPoint畫(huà)線(xiàn)铃在,需要先設(shè)置一個(gè)起始點(diǎn)
//設(shè)置起始點(diǎn)
CGContextMoveToPoint(ctx, 50, 50);
//添加一個(gè)點(diǎn)
CGContextAddLineToPoint(ctx, 100,50);
//在添加一個(gè)點(diǎn)阵具,變成折線(xiàn)
CGContextAddLineToPoint(ctx, 150, 100);
//畫(huà)線(xiàn)方法2
//構(gòu)造線(xiàn)路徑的點(diǎn)數(shù)組
CGPoint points2[] = {CGPointMake(60, 60),CGPointMake(80, 120),CGPointMake(20, 300)};
CGContextAddLines(ctx,points2, 3);
//利用路徑去畫(huà)一組點(diǎn)(推薦使用路徑的方式,雖然多了幾行代碼定铜,但是邏輯更清晰了)
//第一個(gè)路徑
CGMutablePathRef path1 = CGPathCreateMutable();
CGPathMoveToPoint(path1, &CGAffineTransformIdentity, 0, 200);
//CGAffineTransformIdentity 類(lèi)似于初始化一些參數(shù)
CGPathAddLineToPoint(path1, &CGAffineTransformIdentity, 100, 250);
CGPathAddLineToPoint(path1, &CGAffineTransformIdentity, 310, 210);
//路徑1加入context
CGContextAddPath(ctx, path1);
//path同樣有方法CGPathAddLines(),和CGContextAddLines()差不多用戶(hù)阳液,可以自己試下
//描出筆觸
CGContextStrokePath(ctx);
}
2.2:畫(huà)矩形,畫(huà)橢圓,多邊形
//畫(huà)矩形,畫(huà)橢圓揣炕,多邊形
-(void)drawSharp:(CGContextRef)ctx{
CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
//畫(huà)橢圓帘皿,如果長(zhǎng)寬相等就是圓
CGContextAddEllipseInRect(ctx, CGRectMake(0, 250, 50, 50));
//畫(huà)矩形,長(zhǎng)寬相等就是正方形
CGContextAddRect(ctx, CGRectMake(70, 250, 50, 50));
//畫(huà)多邊形,多邊形是通過(guò)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);
}
2.3:畫(huà)圖
//畫(huà)圖片
-(void)drawPicture:(CGContextRef)context{
/*圖片*/
UIImage *image = [UIImage imageNamed:@"head.jpeg"];
[image drawInRect:CGRectMake(10, 300, 100, 100)];//在坐標(biāo)中畫(huà)出圖片
}
2.4:畫(huà)文字
//畫(huà)文字
-(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];
}
2.5:畫(huà)圓畸陡、圓弧鹰溜、貝塞爾曲線(xiàn)
畫(huà)圓和圓弧是一回事虽填,只是起點(diǎn)和終點(diǎn)位置不同,畫(huà)圓畫(huà)弧線(xiàn)主要依賴(lài)于這幾個(gè)方法 CGContextAddArc,CGContextAddArcToPoint, CGContextAddCurveToPoint,CGContextAddQuadCurveToPoint 后面兩個(gè)方法是貝塞爾二次曲線(xiàn)和三次曲線(xiàn)
//畫(huà)圓曹动、圓弧
-(void)drawCircle:(CGContextRef)ctx{
CGContextSetStrokeColorWithColor(ctx, [UIColor purpleColor].CGColor);
/* 繪制路徑 方法一
void CGContextAddArc (
CGContextRef c,
CGFloat x, //圓心的x坐標(biāo)
CGFloat y, //圓心的x坐標(biāo)
CGFloat radius, //圓的半徑
CGFloat startAngle, //開(kāi)始弧度
CGFloat endAngle, //結(jié)束弧度
int clockwise //0表示順時(shí)針斋日,1表示逆時(shí)針
);
*/
//圓
CGContextAddArc (ctx, 100, 100, 50, 0, M_PI* 2 , 0);
CGContextStrokePath(ctx);
//半圓
CGContextAddArc (ctx, 100, 200, 50, 0, M_PI*2, 0);
CGContextStrokePath(ctx);
//繪制路徑 方法二,這方法適合繪制弧度 墓陈,端點(diǎn)p1和p2是弧線(xiàn)的控制點(diǎn)桑驱,類(lèi)似photeshop中鋼筆工具控制曲線(xiàn),還不明白請(qǐng)去了解貝塞爾曲線(xiàn)
// void CGContextAddArcToPoint(
// CGContextRef c,
// CGFloat x1, //端點(diǎn)1的x坐標(biāo)
// CGFloat y1, //端點(diǎn)1的y坐標(biāo)
// CGFloat x2, //端點(diǎn)2的x坐標(biāo)
// CGFloat y2, //端點(diǎn)2的y坐標(biāo)
// 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);
//貝塞爾曲線(xiàn)
CGContextSetStrokeColorWithColor(ctx, [UIColor orangeColor].CGColor);
//三次曲線(xiàn)函數(shù)
//void CGContextAddCurveToPoint (
// CGContextRef c,
// CGFloat cp1x, //控制點(diǎn)1 x坐標(biāo)
// CGFloat cp1y, //控制點(diǎn)1 y坐標(biāo)
// CGFloat cp2x, //控制點(diǎn)2 x坐標(biāo)
// CGFloat cp2y, //控制點(diǎn)2 y坐標(biāo)
// CGFloat x, //直線(xiàn)的終點(diǎn) x坐標(biāo)
// CGFloat y //直線(xiàn)的終點(diǎn) y坐標(biāo)
// );
CGContextMoveToPoint(ctx, 200, 200);
CGContextAddCurveToPoint(ctx, 200, 0, 300, 200, 400, 100);
CGContextStrokePath(ctx);
//三次曲線(xiàn)可以畫(huà)圓弧熬的,比如這里畫(huà)一條之前用CGContextAddArcToPoint構(gòu)成的圓弧
CGContextMoveToPoint(ctx, 200, 200);
CGContextAddCurveToPoint(ctx, 200, 100, 300, 100, 300 ,100);
CGContextStrokePath(ctx);
//二次曲線(xiàn)函數(shù)
//void CGContextAddQuadCurveToPoint (
// CGContextRef c,
// CGFloat cpx, //控制點(diǎn) x坐標(biāo)
// CGFloat cpy, //控制點(diǎn) y坐標(biāo)
// CGFloat x, //直線(xiàn)的終點(diǎn) x坐標(biāo)
// CGFloat y //直線(xiàn)的終點(diǎn) y坐標(biāo)
// );
CGContextMoveToPoint(ctx, 100, 100);
CGContextAddQuadCurveToPoint(ctx, 200, 0, 300, 150);
CGContextStrokePath(ctx);
}