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、付费专栏及课程。

余额充值