Quart2D绘图

一. 绘图的步骤
  两条线的绘画

   
// 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.渲染
    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.渲染
    CGContextStrokePath(ctx);

实现效果:

4.drawrect的理解

// 1.代码为什么要写到drawrect当中
// 因为drawrect能够正确的获取图形上下文(绘图上下文)

// 2.drawrect rect 参数的含义
// rect当前viewbounds

// 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];
}
实现效果:

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);
}
实现效果:

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);

   
// 渲染
    CGContextStrokePath(ctx);

7.C.圆
    // 1.获取上下文
    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);
    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, 10010050, M_PI_2, M_PI, 0);
    CGContextClosePath(ctx);
   
    // 3.渲染
   
//     CGContextStrokePath(ctx);
    CGContextFillPath(ctx);
实现效果:

C 圆饼
    // 1.获取上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    // 2.画饼状图
   
// 画线
    CGContextMoveToPoint(ctx, 100100);
    CGContextAddLineToPoint(ctx, 100150);
    // 画圆弧
    CGContextAddArc(ctx, 10010050, 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 // 切角
    CGContextSetLineJoin(ctx, kCGLineJoinBevel);

4.设置头尾的样式
  // 设置头尾的样式
   
//    kCGLineCapButt, // 默认
   
//    kCGLineCapRound, // 圆角
   
//    kCGLineCapSquare //
    CGContextSetLineCap(ctx, kCGLineCapSquare);
5.设置颜色
   // 设置颜色
   
//    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 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 );
}
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]; // 描边
}
实现效果

五 奇偶填充规则 (奇填偶不填)
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. 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 ];
}
实现效果
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, 那么不填充 , 否则填充
    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 ];
}
实现效果:

饼图(封装)
代码如下

+ ( 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 ];
}
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 ];
}



@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 ];
}
实现效果

操作平移 旋转,  缩放

   
// 获取上下文
//    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);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值