一. 绘图的步骤
两条线的绘画
// 1.获取图形上下文对象
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.向图形上下文中 添加路径 (拼接路径,同时把路径添加到上下文当中)
CGContextMoveToPoint(ctx, 100, 100);
CGContextAddLineToPoint(ctx, 150, 150);
CGContextAddLineToPoint(ctx, 150, 100);
//第二条线
CGContextMoveToPoint(ctx, 50, 50);
CGContextAddLineToPoint(ctx, 80, 80);
// 3.渲染
CGContextStrokePath(ctx);
实现效果:
2.创建可变路径的线
// 2.c
// 1.获取图形上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.拼接路径
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 100, 100);
CGPathAddLineToPoint(path, NULL, 150, 150);
// 3.把路径添加到上下文当中
CGContextAddPath(ctx, path);
// 4.渲染
// 1.获取图形上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.拼接路径
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 100, 100);
CGPathAddLineToPoint(path, NULL, 150, 150);
// 3.把路径添加到上下文当中
CGContextAddPath(ctx, path);
// 4.渲染
CGContextStrokePath(ctx);
3.实现效果
4.实现OC 和C的方法结合绘制一条线
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.创建oc的路径对象
UIBezierPath* path = [[UIBezierPath alloc] init];
[path moveToPoint:CGPointMake(100, 100)];
[path addLineToPoint:CGPointMake(150, 150)];
// 3.把路径对象添加到上下文当中
CGContextAddPath(ctx, path.CGPath);
// 4.渲染
CGContextStrokePath(ctx);
5.实现效果
3.实现OC和OC的可变路径 绘制两条线
// 4. c+oc
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.拼接路径
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 100, 100);
CGPathAddLineToPoint(path, NULL, 150, 150);
UIBezierPath* path1 = [UIBezierPath bezierPathWithCGPath:path];
[path1 addLineToPoint:CGPointMake(150, 100)];
// 3.把路径对象添加到上下文当中
CGContextAddPath(ctx, path1.CGPath);
// 4.渲染
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.拼接路径
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 100, 100);
CGPathAddLineToPoint(path, NULL, 150, 150);
UIBezierPath* path1 = [UIBezierPath bezierPathWithCGPath:path];
[path1 addLineToPoint:CGPointMake(150, 100)];
// 3.把路径对象添加到上下文当中
CGContextAddPath(ctx, path1.CGPath);
// 4.渲染
CGContextStrokePath(ctx);
实现效果:
4.drawrect的理解
// 1.代码为什么要写到drawrect当中
// 因为drawrect能够正确的获取图形上下文(绘图上下文)
// 2.drawrect的 rect 参数的含义
// rect当前view的bounds
// 3.drawrect什么时候调用
// (1)当这个view第一次显示的时候会去调用
// (2)重绘的时候调用
// 4.怎么重绘
// (1)setNeedsDisplay // 整个view重绘
// (2)setNeedsDisplayInRect: // 重绘指定的区域
// 5.为什么不能手动调用
// 因为drawrect能够正确的获取图形上下文(绘图上下文)
// 2.drawrect的 rect 参数的含义
// rect当前view的bounds
// 3.drawrect什么时候调用
// (1)当这个view第一次显示的时候会去调用
// (2)重绘的时候调用
// 4.怎么重绘
// (1)setNeedsDisplay // 整个view重绘
// (2)setNeedsDisplayInRect: // 重绘指定的区域
// 5.为什么不能手动调用
// 因为手动调用的时候不能够确保系统已经创建了正确的上下文
一,绘制练习
1.矩形
[[UIBezierPath bezierPathWithRect:CGRectMake(100, 100, 100, 100)] stroke];
实现效果:
2.圆角矩形
- (void)test2
{
UIBezierPath* path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(100, 100, 100, 100) cornerRadius:20];
[path stroke];
{
UIBezierPath* path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(100, 100, 100, 100) cornerRadius:20];
[path stroke];
}
实现效果:
3.椭圆 是根据矩形的来作的
// oc 椭圆
- (void)test3
{
// oc
UIBezierPath* path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 200, 100)];
[path stroke];
}
实现动画:
4.C语言的椭圆
// c 椭圆
- (void)test4
{
// 获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 拼接路径 同时把路径添加到上下文当中
CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 200, 100));
// 渲染
CGContextStrokePath(ctx);
- (void)test4
{
// 获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 拼接路径 同时把路径添加到上下文当中
CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 200, 100));
// 渲染
CGContextStrokePath(ctx);
}
实现效果:
5.圆弧(顺时针)
UIBezierPath* path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:M_PI_4 clockwise:1];
[path stroke];
// 获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 拼接路径 同时把路径添加到上下文当中
CGContextAddArc(ctx, 150, 150, 100, 0, M_PI_4, 0);
// 渲染
CGContextStrokePath(ctx);
实现效果
6.圆弧(逆时针)
UIBezierPath* path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:M_PI_4 clockwise:0];
[path stroke];
// 获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 拼接路径 同时把路径添加到上下文当中
CGContextAddArc(ctx, 150, 150, 100, 0, M_PI_4, 0);
// 渲染
// 获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 拼接路径 同时把路径添加到上下文当中
CGContextAddArc(ctx, 150, 150, 100, 0, M_PI_4, 0);
// 渲染
CGContextStrokePath(ctx);
7.C.圆
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 画圆
CGContextAddArc(ctx, 100, 100, 50, 0, 2 * M_PI, 0);
// 3.渲染 (注意, 画线只能通过空心来画)
// CGContextFillPath(ctx);
@interface ViewController ()
@property ( weak , nonatomic ) IBOutlet CZView * progressView;
@end
@implementation ViewController
- ( void )viewDidLoad
{
[ super viewDidLoad ];
// Do any additional setup after loading the view, typically from a nib.
self . progressView . progressLabelHidden = NO ;
}
- ( IBAction )progressChange:( UISlider *)sender
{
// NSLog(@"%f", sender.value);
self . progressView . progressValue = sender. value ;
// 获取上下文
// CGContextRef ctx = UIGraphicsGetCurrentContext();
//
// // Current graphics state's Transformation Matrix
//
// // 旋转
// CGContextRotateCTM(ctx, M_PI_4);
//
// // 缩放
CGContextScaleCTM(ctx, 0.5, 0.5);
//
// // 平移
// // CGContextTranslateCTM(ctx, 150, 150);
//
// // 创建路径对象
// UIBezierPath* path = [UIBezierPath bezierPath];
//
// // 圆
// [path addArcWithCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:2 * M_PI clockwise:1];
//
// // 线
// [path moveToPoint:CGPointMake(0, 0)];
// [path addLineToPoint:CGPointMake(300, 300)];
//
// // 把路径添加到上下文当中
// CGContextAddPath(ctx, path.CGPath);
//
// CGContextSetLineWidth(ctx, 20);
//
// // 渲染
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 画圆
CGContextAddArc(ctx, 100, 100, 50, 0, 2 * M_PI, 0);
// 3.渲染 (注意, 画线只能通过空心来画)
// CGContextFillPath(ctx);
CGContextStrokePath(ctx);
实现效果:
8 .C 椭圆
// 画圆
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.画圆
CGContextAddEllipseInRect(ctx, CGRectMake(50, 100, 50, 50));
[[UIColor greenColor] set];
// 3.渲染
// CGContextStrokePath(ctx);
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.画圆
CGContextAddEllipseInRect(ctx, CGRectMake(50, 100, 50, 50));
[[UIColor greenColor] set];
// 3.渲染
// CGContextStrokePath(ctx);
CGContextFillPath(ctx);
// 画椭圆
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.画圆
CGContextAddEllipseInRect(ctx, CGRectMake(50, 100, 100, 230));
[[UIColor purpleColor] set];
// 3.渲染
// CGContextStrokePath(ctx);
CGContextFillPath(ctx);
实现效果
C 圆弧
// 画圆弧
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.画圆弧
// x/y 圆心
// radius 半径
// startAngle 开始的弧度
// endAngle 结束的弧度
// clockwise 画圆弧的方向 (0 顺时针, 1 逆时针)
// CGContextAddArc(ctx, 100, 100, 50, -M_PI_2, M_PI_2, 0);
CGContextAddArc(ctx, 100, 100, 50, M_PI_2, M_PI, 0);
CGContextClosePath(ctx);
// 3.渲染
// CGContextStrokePath(ctx);
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.画圆弧
// x/y 圆心
// radius 半径
// startAngle 开始的弧度
// endAngle 结束的弧度
// clockwise 画圆弧的方向 (0 顺时针, 1 逆时针)
// CGContextAddArc(ctx, 100, 100, 50, -M_PI_2, M_PI_2, 0);
CGContextAddArc(ctx, 100, 100, 50, M_PI_2, M_PI, 0);
CGContextClosePath(ctx);
// 3.渲染
// CGContextStrokePath(ctx);
CGContextFillPath(ctx);
实现效果:
C 圆饼
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.画饼状图
// 画线
CGContextMoveToPoint(ctx, 100, 100);
CGContextAddLineToPoint(ctx, 100, 150);
// 画圆弧
CGContextAddArc(ctx, 100, 100, 50, M_PI_2, M_PI, 0);
// CGContextAddArc(ctx, 100, 100, 50, -M_PI, M_PI_2, 1);
// 关闭路径
CGContextClosePath(ctx);
[[UIColor brownColor]set];
// 3.渲染 (注意, 画线只能通过空心来画)
CGContextFillPath(ctx);
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.画饼状图
// 画线
CGContextMoveToPoint(ctx, 100, 100);
CGContextAddLineToPoint(ctx, 100, 150);
// 画圆弧
CGContextAddArc(ctx, 100, 100, 50, M_PI_2, M_PI, 0);
// CGContextAddArc(ctx, 100, 100, 50, -M_PI, M_PI_2, 1);
// 关闭路径
CGContextClosePath(ctx);
[[UIColor brownColor]set];
// 3.渲染 (注意, 画线只能通过空心来画)
CGContextFillPath(ctx);
// CGContextStrokePath(ctx);
实现效果
三 c.绘图的方式
1. 线宽
//
线宽
CGContextSetLineWidth(ctx, 30);
2.设置链接处的样式
//
设置连接处的样式
// kCGLineJoinMiter, // 默认
// kCGLineJoinRound, // 圆角
// kCGLineJoinBevel // 切角
// kCGLineJoinMiter, // 默认
// kCGLineJoinRound, // 圆角
// kCGLineJoinBevel // 切角
CGContextSetLineJoin(ctx, kCGLineJoinBevel);
4.设置头尾的样式
//
设置头尾的样式
// kCGLineCapButt, // 默认
// kCGLineCapRound, // 圆角
// kCGLineCapSquare // 方
// kCGLineCapButt, // 默认
// kCGLineCapRound, // 圆角
// kCGLineCapSquare // 方
CGContextSetLineCap(ctx, kCGLineCapSquare);
5.设置颜色
//
设置颜色
// CGContextSetRGBStrokeColor(ctx, 0.5, 0.5, 0.5, 1);
// CGContextSetRGBStrokeColor(ctx, 0.5, 0.5, 0.5, 1);
[[UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1] setStroke]
实现效果:
1.OC绘图的样式(常用)
UIBezierPath
* path = [
UIBezierPath
bezierPath
];
[path moveToPoint : CGPointMake ( 50 , 50 )];
[path addLineToPoint : CGPointMake ( 150 , 150 )];
[path addLineToPoint : CGPointMake ( 200 , 50 )];
// 设置线宽
[path setLineWidth : 30 ];
// 设置连接处的样式
[path setLineJoinStyle : kCGLineJoinRound ];
// 设置头尾的样式
[path setLineCapStyle : kCGLineCapRound ];
// 设置颜色
[[ UIColor redColor ] setStroke ];
// 渲染
[path moveToPoint : CGPointMake ( 50 , 50 )];
[path addLineToPoint : CGPointMake ( 150 , 150 )];
[path addLineToPoint : CGPointMake ( 200 , 50 )];
// 设置线宽
[path setLineWidth : 30 ];
// 设置连接处的样式
[path setLineJoinStyle : kCGLineJoinRound ];
// 设置头尾的样式
[path setLineCapStyle : kCGLineCapRound ];
// 设置颜色
[[ UIColor redColor ] setStroke ];
// 渲染
[path stroke];
实现效果
四 渲染的方式
C的渲染方式i(绘制三角形))
// c
渲染方式
- (
void
)test1
{
// 获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext ();
// 拼接路径 同时把路径添加到上下文当中
CGContextMoveToPoint (ctx, 50 , 50 );
CGContextAddLineToPoint (ctx, 100 , 100 );
CGContextAddLineToPoint (ctx, 150 , 50 );
// CGContextAddLineToPoint(ctx, 50, 50);
CGContextClosePath (ctx); // 关闭路径 - 从当前点链接一条线到起始点
// 设置颜色
[[ UIColor redColor ] setStroke ];
[[ UIColor blueColor ] setFill ];
CGContextSetLineWidth (ctx, 10 );
// 渲染
// CGContextDrawPath(ctx, kCGPathStroke); <=> CGContextStrokePath(ctx);
// CGContextDrawPath(ctx, kCGPathFill); <=> CGContextFillPath(ctx);
// CGContextStrokePath(ctx); // 描边
// CGContextFillPath(ctx); // 填充
// CGContextDrawPath(ctx, kCGPathStroke);
// CGContextDrawPath(ctx, kCGPathFill);
CGContextDrawPath (ctx, kCGPathFillStroke );
{
// 获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext ();
// 拼接路径 同时把路径添加到上下文当中
CGContextMoveToPoint (ctx, 50 , 50 );
CGContextAddLineToPoint (ctx, 100 , 100 );
CGContextAddLineToPoint (ctx, 150 , 50 );
// CGContextAddLineToPoint(ctx, 50, 50);
CGContextClosePath (ctx); // 关闭路径 - 从当前点链接一条线到起始点
// 设置颜色
[[ UIColor redColor ] setStroke ];
[[ UIColor blueColor ] setFill ];
CGContextSetLineWidth (ctx, 10 );
// 渲染
// CGContextDrawPath(ctx, kCGPathStroke); <=> CGContextStrokePath(ctx);
// CGContextDrawPath(ctx, kCGPathFill); <=> CGContextFillPath(ctx);
// CGContextStrokePath(ctx); // 描边
// CGContextFillPath(ctx); // 填充
// CGContextDrawPath(ctx, kCGPathStroke);
// CGContextDrawPath(ctx, kCGPathFill);
CGContextDrawPath (ctx, kCGPathFillStroke );
}
OC的渲染方式 (想要填充和描边得两个都写)(绘制三角形)
(
void
)drawRect:(
CGRect
)rect
{
// Drawing code
UIBezierPath * path = [ UIBezierPath bezierPath ];
[path moveToPoint : CGPointMake ( 50 , 50 )];
[path addLineToPoint : CGPointMake ( 100 , 100 )];
[path addLineToPoint : CGPointMake ( 150 , 50 )];
[path addLineToPoint : CGPointMake ( 50 , 50 )];
// [path closePath];
// [[UIColor redColor] setStroke];
//
// [[UIColor blueColor] setFill];
//
[[ UIColor grayColor ] setStroke ];
// [path setLineWidth:10];
[path fill ]; // 填充
// [path stroke]; // 描边
{
// Drawing code
UIBezierPath * path = [ UIBezierPath bezierPath ];
[path moveToPoint : CGPointMake ( 50 , 50 )];
[path addLineToPoint : CGPointMake ( 100 , 100 )];
[path addLineToPoint : CGPointMake ( 150 , 50 )];
[path addLineToPoint : CGPointMake ( 50 , 50 )];
// [path closePath];
// [[UIColor redColor] setStroke];
//
// [[UIColor blueColor] setFill];
//
[[ UIColor grayColor ] setStroke ];
// [path setLineWidth:10];
[path fill ]; // 填充
// [path stroke]; // 描边
}
实现效果
五 奇偶填充规则 (奇填偶不填)
C的奇偶填充规则 KCGPathEOFill)
- (
void
)test1
{
// 1. 获取 " 图形上下文 "
CGContextRef ctx = UIGraphicsGetCurrentContext ();
UIBezierPath * path = [ UIBezierPath bezierPathWithRect : CGRectMake ( 100 , 100 , 200 , 100 )];
UIBezierPath * path1 = [ UIBezierPath bezierPathWithArcCenter : CGPointMake ( 200 , 150 ) radius : 80 startAngle : 0 endAngle : M_PI * 2 clockwise : 1 ];
UIBezierPath * path2 = [ UIBezierPath bezierPathWithRect : CGRectMake ( 250 , 30 , 20 , 200 )];
CGContextAddPath (ctx, path2. CGPath );
CGContextAddPath (ctx, path1. CGPath );
CGContextAddPath (ctx, path. CGPath );
// 说明 : 被覆盖过奇数次的点填充 , 被覆盖过偶数次的点不填充
// 奇填偶不填
CGContextDrawPath (ctx, kCGPathEOFill );
{
// 1. 获取 " 图形上下文 "
CGContextRef ctx = UIGraphicsGetCurrentContext ();
UIBezierPath * path = [ UIBezierPath bezierPathWithRect : CGRectMake ( 100 , 100 , 200 , 100 )];
UIBezierPath * path1 = [ UIBezierPath bezierPathWithArcCenter : CGPointMake ( 200 , 150 ) radius : 80 startAngle : 0 endAngle : M_PI * 2 clockwise : 1 ];
UIBezierPath * path2 = [ UIBezierPath bezierPathWithRect : CGRectMake ( 250 , 30 , 20 , 200 )];
CGContextAddPath (ctx, path2. CGPath );
CGContextAddPath (ctx, path1. CGPath );
CGContextAddPath (ctx, path. CGPath );
// 说明 : 被覆盖过奇数次的点填充 , 被覆盖过偶数次的点不填充
// 奇填偶不填
CGContextDrawPath (ctx, kCGPathEOFill );
}
1. OC奇偶填充规则 (UsesEvenoddFillRule = YES)
- (
void
)drawRect:(
CGRect
)rect
{
// oc 奇偶填充规则
UIBezierPath * path = [ UIBezierPath bezierPathWithRect : CGRectMake ( 100 , 100 , 200 , 100 )];
[path addArcWithCenter : CGPointMake ( 150 , 150 ) radius : 100 startAngle : 0 endAngle : 2 * M_PI clockwise : 1 ];
path. usesEvenOddFillRule = YES ;
[path fill ];
{
// oc 奇偶填充规则
UIBezierPath * path = [ UIBezierPath bezierPathWithRect : CGRectMake ( 100 , 100 , 200 , 100 )];
[path addArcWithCenter : CGPointMake ( 150 , 150 ) radius : 100 startAngle : 0 endAngle : 2 * M_PI clockwise : 1 ];
path. usesEvenOddFillRule = YES ;
[path fill ];
}
实现效果
1. 非零环绕数规则( OC和C)
- (
void
)drawRect:(
CGRect
)rect
{
// 1. 获取 " 图形上下文 "
CGContextRef ctx = UIGraphicsGetCurrentContext ();
UIBezierPath * path = [ UIBezierPath bezierPathWithArcCenter : CGPointMake ( 150 , 150 ) radius : 100 startAngle : 0 endAngle : M_PI * 2 clockwise : 1 ];
UIBezierPath * path1 = [ UIBezierPath bezierPathWithArcCenter : CGPointMake ( 150 , 150 ) radius : 50 startAngle : 0 endAngle : M_PI * 2 clockwise : 0 ];
CGContextAddPath (ctx, path1. CGPath );
CGContextAddPath (ctx, path. CGPath );
// 默认填充模式 : nonzero winding number rule( 非零绕数规则 ) 从左到右跨过 , +1 。从右到左跨过 , -1 。最后如果为 0, 那么不填充 , 否则填充
{
// 1. 获取 " 图形上下文 "
CGContextRef ctx = UIGraphicsGetCurrentContext ();
UIBezierPath * path = [ UIBezierPath bezierPathWithArcCenter : CGPointMake ( 150 , 150 ) radius : 100 startAngle : 0 endAngle : M_PI * 2 clockwise : 1 ];
UIBezierPath * path1 = [ UIBezierPath bezierPathWithArcCenter : CGPointMake ( 150 , 150 ) radius : 50 startAngle : 0 endAngle : M_PI * 2 clockwise : 0 ];
CGContextAddPath (ctx, path1. CGPath );
CGContextAddPath (ctx, path. CGPath );
// 默认填充模式 : nonzero winding number rule( 非零绕数规则 ) 从左到右跨过 , +1 。从右到左跨过 , -1 。最后如果为 0, 那么不填充 , 否则填充
CGContextDrawPath(ctx, kCGPathFill);
六 .小案例 饼图
animation.
- ( void )drawRect:( CGRect )rect
{
// Drawing code
NSArray * array = @[ @0.3 , @0.2 , @0.4 , @0.1 ] ;
CGFloat start = 0 ;
CGFloat end = 0 ;
for ( int i = 0 ; i < array. count ; i++) {
// 计算结束的位置 等于整个圆 * 数据的百分比 再 加上 start
end = 2 * M_PI * [array[i] floatValue ] + start;
UIBezierPath * path = [ UIBezierPath bezierPathWithArcCenter : CGPointMake ( 150 , 150 ) radius : 100 startAngle :start endAngle :end clockwise : 1 ];
// 画扇形需要往圆心连线
[path addLineToPoint : CGPointMake ( 150 , 150 )];
[[ self randomColor ] set ];
[path fill ];
// 下一次的起点 等于 上一次的 ��
start = end;
}
}
// 点击 view 的时候调用
- ( void )touchesBegan:( NSSet *)touches withEvent:( UIEvent *)event
{
// 重绘
// [self setNeedsDisplay];
[ self setNeedsDisplayInRect : CGRectMake ( 0 , 0 , 150 , 150 )];
}
// 随机颜色
- ( UIColor *)randomColor
{
CGFloat r = arc4random () % 256 / 255.0 ;
CGFloat g = arc4random () % 256 / 255.0 ;
CGFloat b = arc4random () % 256 / 255.0 ;
return [ UIColor colorWithRed :r green :g blue :b alpha : 1 ];
- ( void )drawRect:( CGRect )rect
{
// Drawing code
NSArray * array = @[ @0.3 , @0.2 , @0.4 , @0.1 ] ;
CGFloat start = 0 ;
CGFloat end = 0 ;
for ( int i = 0 ; i < array. count ; i++) {
// 计算结束的位置 等于整个圆 * 数据的百分比 再 加上 start
end = 2 * M_PI * [array[i] floatValue ] + start;
UIBezierPath * path = [ UIBezierPath bezierPathWithArcCenter : CGPointMake ( 150 , 150 ) radius : 100 startAngle :start endAngle :end clockwise : 1 ];
// 画扇形需要往圆心连线
[path addLineToPoint : CGPointMake ( 150 , 150 )];
[[ self randomColor ] set ];
[path fill ];
// 下一次的起点 等于 上一次的 ��
start = end;
}
}
// 点击 view 的时候调用
- ( void )touchesBegan:( NSSet *)touches withEvent:( UIEvent *)event
{
// 重绘
// [self setNeedsDisplay];
[ self setNeedsDisplayInRect : CGRectMake ( 0 , 0 , 150 , 150 )];
}
// 随机颜色
- ( UIColor *)randomColor
{
CGFloat r = arc4random () % 256 / 255.0 ;
CGFloat g = arc4random () % 256 / 255.0 ;
CGFloat b = arc4random () % 256 / 255.0 ;
return [ UIColor colorWithRed :r green :g blue :b alpha : 1 ];
}
实现效果:
饼图(封装)
代码如下
+ (
instancetype
)czview
{
return [[ NSBundle mainBundle ] loadNibNamed : @"CZView" owner : nil options : nil ][ 0 ];
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- ( void )drawRect:( CGRect )rect
{
// Drawing code
if (!( self . bounds . size . width == self . bounds . size . height )) {
// 报错
NSException * ex = [ NSException exceptionWithName : @" 你看看你的宽高是不是一样 再来用吧 " reason : @" 宽高不相等 " userInfo : nil ];
[ex raise ];
}
// NSArray* array = @[ @0.3, @0.2, @0.4, @0.1 ];
CGFloat start = 0 ;
CGFloat end = 0 ;
for ( int i = 0 ; i < self . values . count ; i++) {
// 计算结束的位置 等于整个圆 * 数据的百分比 再 加上 start
end = 2 * M_PI * [ self . values [i] floatValue ] + start;
UIBezierPath * path = [ UIBezierPath bezierPathWithArcCenter :[ self arcCenter ] radius : MIN ( self . bounds . size . width , self . bounds . size . height ) * 0.5 - 10 startAngle :start endAngle :end clockwise : 1 ];
// 画扇形需要往圆心连线
[path addLineToPoint :[ self arcCenter ]];
[[ self randomColor ] set ];
[path fill ];
// 下一次的起点 等于 上一次的 ��
start = end;
}
}
- ( CGPoint )arcCenter
{
return CGPointMake ( self . bounds . size . width * 0.5 , self . bounds . size . height * 0.5 );
}
// 点击 view 的时候调用
- ( void )touchesBegan:( NSSet *)touches withEvent:( UIEvent *)event
{
// 重绘
[ self setNeedsDisplay ];
// [self setNeedsDisplayInRect:CGRectMake(0, 0, 150, 150)];
}
// 随机颜色
- ( UIColor *)randomColor
{
CGFloat r = arc4random () % 256 / 255.0 ;
CGFloat g = arc4random () % 256 / 255.0 ;
CGFloat b = arc4random () % 256 / 255.0 ;
return [ UIColor colorWithRed :r green :g blue :b alpha : 1 ];
{
return [[ NSBundle mainBundle ] loadNibNamed : @"CZView" owner : nil options : nil ][ 0 ];
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- ( void )drawRect:( CGRect )rect
{
// Drawing code
if (!( self . bounds . size . width == self . bounds . size . height )) {
// 报错
NSException * ex = [ NSException exceptionWithName : @" 你看看你的宽高是不是一样 再来用吧 " reason : @" 宽高不相等 " userInfo : nil ];
[ex raise ];
}
// NSArray* array = @[ @0.3, @0.2, @0.4, @0.1 ];
CGFloat start = 0 ;
CGFloat end = 0 ;
for ( int i = 0 ; i < self . values . count ; i++) {
// 计算结束的位置 等于整个圆 * 数据的百分比 再 加上 start
end = 2 * M_PI * [ self . values [i] floatValue ] + start;
UIBezierPath * path = [ UIBezierPath bezierPathWithArcCenter :[ self arcCenter ] radius : MIN ( self . bounds . size . width , self . bounds . size . height ) * 0.5 - 10 startAngle :start endAngle :end clockwise : 1 ];
// 画扇形需要往圆心连线
[path addLineToPoint :[ self arcCenter ]];
[[ self randomColor ] set ];
[path fill ];
// 下一次的起点 等于 上一次的 ��
start = end;
}
}
- ( CGPoint )arcCenter
{
return CGPointMake ( self . bounds . size . width * 0.5 , self . bounds . size . height * 0.5 );
}
// 点击 view 的时候调用
- ( void )touchesBegan:( NSSet *)touches withEvent:( UIEvent *)event
{
// 重绘
[ self setNeedsDisplay ];
// [self setNeedsDisplayInRect:CGRectMake(0, 0, 150, 150)];
}
// 随机颜色
- ( UIColor *)randomColor
{
CGFloat r = arc4random () % 256 / 255.0 ;
CGFloat g = arc4random () % 256 / 255.0 ;
CGFloat b = arc4random () % 256 / 255.0 ;
return [ UIColor colorWithRed :r green :g blue :b alpha : 1 ];
}
CZView *View = [CZView czview];
View.View1 = @[@0.5,@0.7,@).5];
View.frame = CGRectMacke(0,0,300,300);
[self.view addSwid :View];
实现效果
七 自定义进度条
animation.
- ( void )drawRect:( CGRect )rect
{
// Drawing code
if ( self . progressLabelHidden == YES ) {
self . progressLabel . hidden = YES ;
}
self . progressLabel . text = [ NSString stringWithFormat : @"%.2f%%" , self . progressValue * 100 ];
UIBezierPath * path = [ UIBezierPath bezierPathWithArcCenter : CGPointMake ( 150 , 150 ) radius : 100 startAngle : 0 - M_PI_2 endAngle : 2 * M_PI * self . progressValue - M_PI_2 clockwise : 1 ];
// 忘中心连线
[path addLineToPoint : CGPointMake ( 150 , 150 )];
[[ UIColor blueColor ] set ];
[path fill ];
- ( void )drawRect:( CGRect )rect
{
// Drawing code
if ( self . progressLabelHidden == YES ) {
self . progressLabel . hidden = YES ;
}
self . progressLabel . text = [ NSString stringWithFormat : @"%.2f%%" , self . progressValue * 100 ];
UIBezierPath * path = [ UIBezierPath bezierPathWithArcCenter : CGPointMake ( 150 , 150 ) radius : 100 startAngle : 0 - M_PI_2 endAngle : 2 * M_PI * self . progressValue - M_PI_2 clockwise : 1 ];
// 忘中心连线
[path addLineToPoint : CGPointMake ( 150 , 150 )];
[[ UIColor blueColor ] set ];
[path fill ];
}
@interface ViewController ()
@property ( weak , nonatomic ) IBOutlet CZView * progressView;
@end
@implementation ViewController
- ( void )viewDidLoad
{
[ super viewDidLoad ];
// Do any additional setup after loading the view, typically from a nib.
self . progressView . progressLabelHidden = NO ;
}
- ( IBAction )progressChange:( UISlider *)sender
{
// NSLog(@"%f", sender.value);
self . progressView . progressValue = sender. value ;
[self.progressView setNeedsDisplay
实现效果
八 柱状体
- (
void
)drawRect:(
CGRect
)rect
{
// Drawing code
// 数据
NSArray * array = @[ @1.0 , @0.8 , @0.3 , @0.4 , @0.5 , @0.2 ] ;
for ( int i = 0 ; i < array. count ; i++) {
CGFloat w = 20 ;
CGFloat h = self . bounds . size . height * [array[i] floatValue ];
CGFloat x = i * w * 2 ;
CGFloat y = self . bounds . size . height - h;
UIBezierPath * path = [ UIBezierPath bezierPathWithRect : CGRectMake (x, y, w, h)];
// 设置颜色
[[ self randomColor ] set ];
[path fill ];
}
}
// 随机颜色
- ( UIColor *)randomColor
{
CGFloat r = arc4random () % 256 / 255.0 ;
CGFloat g = arc4random () % 256 / 255.0 ;
CGFloat b = arc4random () % 256 / 255.0 ;
return [ UIColor colorWithRed :r green :g blue :b alpha : 1 ];
{
// Drawing code
// 数据
NSArray * array = @[ @1.0 , @0.8 , @0.3 , @0.4 , @0.5 , @0.2 ] ;
for ( int i = 0 ; i < array. count ; i++) {
CGFloat w = 20 ;
CGFloat h = self . bounds . size . height * [array[i] floatValue ];
CGFloat x = i * w * 2 ;
CGFloat y = self . bounds . size . height - h;
UIBezierPath * path = [ UIBezierPath bezierPathWithRect : CGRectMake (x, y, w, h)];
// 设置颜色
[[ self randomColor ] set ];
[path fill ];
}
}
// 随机颜色
- ( UIColor *)randomColor
{
CGFloat r = arc4random () % 256 / 255.0 ;
CGFloat g = arc4random () % 256 / 255.0 ;
CGFloat b = arc4random () % 256 / 255.0 ;
return [ UIColor colorWithRed :r green :g blue :b alpha : 1 ];
}
实现效果
操作平移 旋转, 缩放
// 获取上下文
// CGContextRef ctx = UIGraphicsGetCurrentContext();
//
// // Current graphics state's Transformation Matrix
//
// // 旋转
// CGContextRotateCTM(ctx, M_PI_4);
//
// // 缩放
CGContextScaleCTM(ctx, 0.5, 0.5);
//
// // 平移
// // CGContextTranslateCTM(ctx, 150, 150);
//
// // 创建路径对象
// UIBezierPath* path = [UIBezierPath bezierPath];
//
// // 圆
// [path addArcWithCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:2 * M_PI clockwise:1];
//
// // 线
// [path moveToPoint:CGPointMake(0, 0)];
// [path addLineToPoint:CGPointMake(300, 300)];
//
// // 把路径添加到上下文当中
// CGContextAddPath(ctx, path.CGPath);
//
// CGContextSetLineWidth(ctx, 20);
//
// // 渲染
// CGContextStrokePath(ctx);
实现效果
九 图形上下文栈
十 . 关于可变路径的内存管理问题
1. 解决办法
CFRelease(path);