ios基础篇(六)—— Quartz2D 饼状图、柱状图

一、绘制“饼状图”

   

思路

  • 构建数据,NSArray *data = @[@30, @15, @5, @17, @3, @10, @20];。
  • 根据数据个数绘制“扇形”(弧)

注意

  •    每个弧的起始、结束弧度都是不一样的
  •    每次绘制完毕一个弧以后都要重新设置下一次的起始弧度为当前的结束弧度
  •    本次绘制的结束弧度,为起始弧度+本次的弧度

如果画完圆弧之后直接fill填充 则先关闭路径,后直接填充

    

画扇形,需加一个连往圆心的线  填充时 先自动关闭路径,后填充

给每个扇形区域 随机一个颜色  

         

 

 touchBegan 在哪个view写就相当于点击谁 重绘 只有颜色在变化 相当于刷新tableview的感觉

 setNeedDisplayInRect :重绘指定的区域 1/4   只有左上角1/4的颜色在换

二、绘制“柱状图”

   

  • 1.构建数据, NSArray *data = @[@300, @150.65, @55.3, @507.7, @95.8, @700, @650.65];
  • 2.根据数据的个数绘制柱状图。
  • 3.计算每个柱子的 x,y,w,h 即可

    

 三、绘制“下载进度条”

思路:

  1. 在控制器中将 slider 的值传递给自定义 view
  2. 在自定义 View中,根据传递过来的值绘制弧。
  3. 创建一个与自定义 view 一样大小的 label 来显示下载进度 

ProgressView.m

#import "ProgressView.h"
@interface ProgressView ()
@property (weak, nonatomic) IBOutlet UILabel* label;
@end

@implementation ProgressView
- (void)drawRect:(CGRect)rect
{
    // 两个百分号等于一个百分号
    self.label.text = [NSString stringWithFormat:@"%.2f%%", self.values * 100];

    UIBezierPath* path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) 
                radius:100 startAngle:-M_PI_2 endAngle:2 * M_PI * self.values - M_PI_2 clockwise:YES];
    [path addLineToPoint:CGPointMake(150, 150)];
    [[UIColor redColor] set];
    [path fill];
}
@end

ProgressView.h

#import <UIKit/UIKit.h>

@interface ProgressView : UIView
@property (nonatomic, assign) CGFloat values;
@end

ViewController.m

#import "ViewController.h"
#import "ProgressView.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet ProgressView* progressView;
@end

@implementation ViewController
// slider 控件的监听
- (IBAction)slide:(UISlider*)sender
{
    // 通过value 获取当前 slider 上按钮的位置
    NSLog(@"%f", sender.value);
    self.progressView.values = sender.value;
    // 重绘
    [self.progressView setNeedsDisplay];
}
@end

Quartz2D api常用拼接路径函数

新建一个起点

 void CGContextMoveToPoint(CGContextRef c, CGFloat x, CGFloat y) 

添加新的线段到某个点

void CGContextAddLineToPoint(CGContextRef c, CGFloat x, CGFloat y) 

添加一个矩形

 void CGContextAddRect(CGContextRef c, CGRect rect) 

添加一个椭圆

void CGContextAddEllipseInRect(CGContextRef context, CGRect rect)

添加一个圆弧

void CGContextAddArc(CGContextRef c, CGFloat x, CGFloat y, CGFloat radius,
                      CGFloat startAngle, CGFloat endAngle, int clockwise)

常用绘制路径函数

Mode参数决定绘制的模式

 void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode) 

绘制空心路径

 void CGContextStrokePath(CGContextRef c) 

绘制实心路径

void CGContextFillPath(CGContextRef c)

提示:一般以CGContextDraw、CGContextStroke、CGContextFill开头的函数,都是用来绘制路径的

// 获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();

// 创建可变路径(c)
CGMutablePathRef path = CGPathCreateMutable();

// 把路径放在上下文当中
CGContextAddPath(ctx, path);


// 创建路径对象(oc)
UIBezierPath* path = [UIBezierPath bezierPath];

// 渲染
CGContextStrokePath(ctx);

// --- 绘图的步骤
// 1.获取图形上下文
// 2.拼接路径 同时 添加到上下文当中
// 3.渲染

// --- 绘图的方式5种
// 1.c 直接在上下文当中去拼接路径
// 2.c 先拼接路径 再把路径添加到上下文当中
// 3.c + oc 基本等同于第二种 把oc的path 转化成 CGPath
// 4.c + oc 把CGPath 转化成 oc的path
// 5.oc 声明path对象 拼接路径 渲染

// --- 关于drawrect
// 1.为什么代码要写在drawrect里面
// 因为只有在这个方法当中才能获取正确的上下文
// 2.drawrect方法中rect参数的含义是什么
// rect是当前view的bounds
// 3.drawrect什么时候调用

// 系统自动调用
// (1)当这个view第一次显示的时候调用
// (2)当重绘的时候调用
// 4.如何重绘
// view的setNeedsDisplay方法
// view的setNeedsDisplayInRect方法  rect参数是刷新指定的区域

// 5.为什么drawRect不要手动调用
//因为系统调的时候是会确保创建view的上下文
// 手动调用的时候可能获取不到

// --- 绘图的样式
// 设置线宽
CGContextSetLineWidth(ctx, 20);

// 设置连接处的样式
CGContextSetLineJoin(ctx, kCGLineJoinRound);

// 设置头尾的样式
CGContextSetLineCap(ctx, kCGLineCapRound);

// 设置线的宽度
[path setLineWidth:30];

//       kCGLineJoinMiter, // 默认的效果
//       kCGLineJoinRound, // 圆角
//       kCGLineJoinBevel // 切角


// 设置连接处的样式
[path setLineJoinStyle:kCGLineJoinBevel];
//       kCGLineCapButt, // 默认
//       kCGLineCapRound, // 圆角
//       kCGLineCapSquare

// 设置头尾的样式
[path setLineCapStyle:kCGLineCapButt];

// --- 绘图的渲染的方式
// oc
[path stroke];
[path fill];

// c
// CGContextDrawPath(ctx, kCGPathStroke); <==> CGContextStrokePath(ctx);
// CGContextDrawPath(ctx, kCGPathFill); <==> CGContextFillPath(ctx);

// 既描边又填充
// c:
CGContextDrawPath(ctx, kCGPathFillStroke);

// oc: 两句话都执行
[path stroke];
[path fill];

// --- 奇偶填充规则
// c
CGContextDrawPath(ctx, kCGPathEOFill);

// oc
path.usesEvenOddFillRule = YES;

// 奇填偶不填
// --- 非零绕数
// 默认填充模式: nonzero winding number rule(非零绕数规则)从左到右跨过, +1。从右到左跨过, -1。最后如果为0, 那么不填充, 否则填充

// 验证 取区域中 任意一个点 拉一条射线 看图形与射线的交叉点 是从左往右还是从右往左
// --- 饼图
// 随机颜色
- (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];
}

// 比较最小的值
MIN(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5)

// 画扇形的时候 记得往圆心 连一条线

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值