iOS图形绘制 UIBezierPath 绘制折线图、柱状图、饼形图

iOS图形绘制 UIBezierPath 绘制折线图、柱状图以及饼形图(感谢Mr_Wendao,如果想查看饼形图源码请点击连接,饼形图我借鉴了Mr_Wendao的代码学习,再次感谢)。

先看一下代码的效果图 如下图
这里写图片描述

下面是主要代码

在初始化的时候设置绘图类型
typedef NS_ENUM(NSInteger) {
    LineChart_Type = 0,//折线图
    PieChart_Type = 1, //饼形图
    BarChart_Type = 2  //柱状图
}DrawViewType;

@interface AXDrawView : UIView<CAAnimationDelegate>

//自定义初始化方法
-(id)initWithFrame:(CGRect)frame type:(DrawViewType)type;

//绘图类型
@property(nonatomic ,assign)DrawViewType drawType;
//折线图数据数组
@property(nonatomic ,strong)NSMutableArray *arrayPoint;
//折线图开始点
@property(nonatomic ,assign)CGPoint startPint;
//折线图结束点
@property(nonatomic ,assign)CGPoint endPoint;

//饼形图颜色数据
@property(nonatomic ,strong)NSArray *colorItems;

@end

下面是实现代码

//图标上下左右边距
#define UP    10.0
#define BELOW 30.0
#define LEFT  30.0
#define RIGHT 10.0

自定义初始化方法
-(id)initWithFrame:(CGRect)frame type:(DrawViewType)type
{
    self = [super initWithFrame:frame];
    if (self) {
        if (!_scaleArray) {
            _scaleArray = [[NSArray alloc] initWithObjects:@"iOS",@"Java",@"PHP",@"HTML",@"Android",@"C语言",@"C++", nil];
        }
        _drawType = type;
        switch (_drawType) {
            case LineChart_Type:
            {
                UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];
                [self addGestureRecognizer:longPressGesture];
            }
                break;
            case PieChart_Type:
            {

            }
                break;
            case BarChart_Type:
            {
                UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];
                [self addGestureRecognizer:longPressGesture];
            }
                break;
            default:
                break;
        }
    }
    return self;
}

重写drawRect方法
- (void)drawRect:(CGRect)rect {
    // Drawing code
    [super drawRect:rect];

    if (_drawType != PieChart_Type) {
        [self drawScale];
    }

    switch (_drawType) {
        case LineChart_Type:
        {
            [self drawLineChart];
        }
            break;
        case PieChart_Type:
        {
            [self pieChartAction];
        }
            break;
        case BarChart_Type:
        {
            [self drawBarChart];
        }
            break;
        default:
            break;
    }
}

折线图以及柱状图需要坐标刻度,在绘制这两种图标是需要调用一下方法
//绘制刻度
-(void)drawScale
{
    UIBezierPath *scalePath = [UIBezierPath bezierPath];
    [scalePath moveToPoint:CGPointMake(30, 10)];
    [scalePath addLineToPoint:CGPointMake(30, self.frame.size.height - BELOW)];
    [scalePath moveToPoint:CGPointMake(30, self.frame.size.height - BELOW)];
    [scalePath addLineToPoint:CGPointMake(self.frame.size.width - RIGHT, self.frame.size.height - BELOW)];
    CGFloat scaleY = (self.frame.size.height - UP - BELOW) / 10.0;
    for (int i = 0; i < 10; i++) {
        [scalePath moveToPoint:CGPointMake(LEFT, (self.frame.size.height - BELOW) - (scaleY * i))];
        [scalePath addLineToPoint:CGPointMake(LEFT + 2, (self.frame.size.height - BELOW) - (scaleY * i))];
        UILabel *yLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 30, 20)];
        yLabel.textColor = [UIColor redColor];
        yLabel.font = [UIFont systemFontOfSize:10];
        yLabel.textAlignment = NSTextAlignmentCenter;
        yLabel.text = [NSString stringWithFormat:@"%d",i * 10];
        yLabel.center = CGPointMake(LEFT / 2, (self.frame.size.height - BELOW) - (scaleY * i));
        [self addSubview:yLabel];
    }
    CGFloat scaleX = (self.frame.size.width - LEFT - RIGHT) / 8.0;
    for (int i = 0; i < 8; i++) {
        [scalePath moveToPoint:CGPointMake((LEFT + scaleX * i), self.frame.size.height - BELOW)];
        [scalePath addLineToPoint:CGPointMake((LEFT + scaleX * i), self.frame.size.height - BELOW - 2)];
        if (i > 0) {
            UILabel *xLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, scaleX, 20)];
            xLabel.textColor = [UIColor redColor];
            xLabel.font = [UIFont systemFontOfSize:10];
            xLabel.textAlignment = NSTextAlignmentCenter;
            xLabel.text = [_scaleArray objectAtIndex:i - 1];
            xLabel.center = CGPointMake((LEFT + scaleX * i), self.frame.size.height - BELOW / 2);
            [self addSubview:xLabel];
        }
    }

    CAShapeLayer *shaperLayer = [CAShapeLayer layer];
    shaperLayer.path = scalePath.CGPath;
    shaperLayer.lineWidth = 1.0;
    shaperLayer.lineCap = kCALineCapRound;
    shaperLayer.lineJoin = kCALineJoinRound;
    shaperLayer.strokeColor = [UIColor grayColor].CGColor;
    [self.layer addSublayer:shaperLayer];
}

当获取到数据,需要对数据进行处理主要代码如下
//重写set方法,图标数据信息信息
-(void)setArrayPoint:(NSArray *)arrayPoint
{
    if (!_arrayPoint) {
        _arrayPoint = [NSMutableArray array];
    }
    if (_drawType == LineChart_Type) {
        [_arrayPoint addObjectsFromArray:[self disposePointArray:arrayPoint]];
        _startPint = CGPointFromString([_arrayPoint objectAtIndex:0]);
        [self drawAction];
    }else if (_drawType == PieChart_Type){
        [_arrayPoint addObjectsFromArray:[self disposePointArray:arrayPoint]];
        [self setNeedsDisplay];
    }else if (_drawType == BarChart_Type){
        [_arrayPoint addObjectsFromArray:[self disposePointArray:arrayPoint]];
        _startPint = CGPointMake((self.frame.size.width - LEFT - RIGHT) / 8 + LEFT, self.frame.size.height - BELOW);
        _endPoint = CGPointFromString([_arrayPoint objectAtIndex:0]);
        [self setNeedsDisplay];
    }
}

//处理数据获取绘图点
-(NSMutableArray *)disposePointArray:(NSArray *)array
{
    if (_drawType == PieChart_Type) {
        NSMutableArray *points = [NSMutableArray array];
        CGFloat allFloat = 0.0;
        for (NSString *string in array) {
            allFloat = allFloat + [string floatValue];
        }
        for (NSString *string in array) {
            CGFloat f = [string floatValue] / allFloat;
            [points addObject:[NSString stringWithFormat:@"%.2f",f]];
        }
        return points;
    }else{
        NSMutableArray *points = [NSMutableArray array];
        for (int i = 0; i < array.count; i++) {
            NSString *string = [array objectAtIndex:i];
            CGFloat y = (self.frame.size.height - BELOW) - ([string floatValue] / 100.0 * (self.frame.size.height - BELOW - UP));
            CGPoint point = CGPointMake(LEFT + ((self.frame.size.width - LEFT - RIGHT) / 8.0 * (i + 1)), y);
            [points addObject:NSStringFromCGPoint(point)];
        }
        return points;
    }
}

//获取开始、结束点
-(void)drawAction
{
    _number++;
    if (_drawType == LineChart_Type) {
        if (_number < _arrayPoint.count) {
            NSString *pointStr = [_arrayPoint objectAtIndex:_number];
            _endPoint = CGPointFromString(pointStr);
            [self setNeedsDisplay];
        }
    }else if (_drawType == BarChart_Type){
        if (_number < _arrayPoint.count) {
            CGFloat scaleX = (self.frame.size.width - LEFT - RIGHT) / 8.0;
            _startPint = CGPointMake((self.frame.size.width - LEFT - RIGHT) / 8 + LEFT + scaleX * _number, self.frame.size.height - BELOW);
            NSString *pointStr = [_arrayPoint objectAtIndex:_number];
            _endPoint = CGPointFromString(pointStr);
            [self setNeedsDisplay];
        }
    }
}

下面的代码是绘图的主要代码

折线图
-(void)drawLineChart
{
    UIBezierPath *path = [UIBezierPath bezierPath];
    //绘制圆点
    [path addArcWithCenter:_startPint radius:3.0 startAngle:0.0 endAngle:M_PI*2 clockwise:YES];
    //设置描边宽度(为了让描边看上去更清楚)
    [path setLineWidth:3.0];
    //描边和填充
    [path stroke];
    [path fill];
    //绘制折线图
    [path moveToPoint:_startPint];
    [path addLineToPoint:_endPoint];
    path.lineJoinStyle = kCGLineJoinRound;
    //设置layer层
    CAShapeLayer *shaperLayer = [CAShapeLayer layer];
    shaperLayer.path = path.CGPath;
    shaperLayer.lineWidth = 2.0;
    shaperLayer.lineCap = kCALineCapRound;
    shaperLayer.lineJoin = kCALineJoinRound;
    shaperLayer.strokeColor = [UIColor whiteColor].CGColor;
    shaperLayer.fillColor = [UIColor whiteColor].CGColor;

    //设置动画
    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:NSStringFromSelector(@selector(strokeEnd))];
    anim.delegate = self;
    anim.fromValue = @0;
    anim.toValue = @1;
    anim.duration = 0.1;

    [shaperLayer addAnimation:anim forKey:NSStringFromSelector(@selector(strokeEnd))];
    [self.layer addSublayer:shaperLayer];
    //将结束点设置为起始点
    _startPint = _endPoint;
    //绘制最后一个点
    if (_number == _arrayPoint.count - 1) {
        UIBezierPath *paths = [UIBezierPath bezierPath];
        // 添加圆到path
        [paths addArcWithCenter:_startPint radius:3.0 startAngle:0.0 endAngle:M_PI*2 clockwise:YES];
        // 设置描边宽度(为了让描边看上去更清楚)
        [paths setLineWidth:3.0];
        // 描边和填充
        [paths stroke];
        [paths fill];

        CAShapeLayer *shaperLayer = [CAShapeLayer layer];
        shaperLayer.path = paths.CGPath;
        shaperLayer.lineWidth = 2.0;
        shaperLayer.strokeColor = [UIColor whiteColor].CGColor;
        shaperLayer.fillColor = [UIColor whiteColor].CGColor;

        CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:NSStringFromSelector(@selector(strokeEnd))];
        anim.delegate = self;
        anim.fromValue = @0;
        anim.toValue = @1;
        anim.duration = 0.5;

        [shaperLayer addAnimation:anim forKey:NSStringFromSelector(@selector(strokeEnd))];
        [self.layer addSublayer:shaperLayer];
    }
}

柱状图
//绘制柱状图
-(void)drawBarChart
{
    UIBezierPath *path = [UIBezierPath bezierPath];
    //绘制折线图
    [path moveToPoint:_startPint];
    [path addLineToPoint:_endPoint];
    path.lineJoinStyle = kCGLineJoinRound;
    //设置layer层
    CAShapeLayer *shaperLayer = [CAShapeLayer layer];
    shaperLayer.path = path.CGPath;
    CGFloat scaleX = (self.frame.size.width - LEFT - RIGHT) / 8.0;
    shaperLayer.lineWidth = scaleX;
    shaperLayer.strokeColor = kPieRandColor.CGColor;
    //shaperLayer.fillColor = kPieRandColor.CGColor;
    //设置动画
    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:NSStringFromSelector(@selector(strokeEnd))];
    anim.delegate = self;
    anim.fromValue = @0;
    anim.toValue = @1;
    anim.duration = 0.1;

    [shaperLayer addAnimation:anim forKey:NSStringFromSelector(@selector(strokeEnd))];
    [self.layer addSublayer:shaperLayer];
}
这里监听绘图动画结束,折线图以及柱状图实现绘制动画
#pragma mark CAAnimationDelegate 监听动画结束
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    if (_drawType == LineChart_Type) {
        if (flag) {
            [self drawAction];
        }
    }else if (_drawType == BarChart_Type){
        if (flag) {
            [self drawAction];
        }
    }
}

以上就是绘制图标的主要代码,希望对大家有帮助,如果大家有更好的思路或者更简洁的方法,希望大家多多指教。下面是源码连接
DEMO源码连接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值