iOS开发中利用贝塞尔曲线画饼状图

2022-02-24  本文已影响0人  梁森的简书

看.m中的代码

#import "BezierView.h"

#define Color(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0]
#define RandomColor  Color(arc4random_uniform(256), arc4random_uniform(256), arc4random_uniform(256))

@interface BezierView ()
/// 中间镂空部分的layer
@property (nonatomic,strong) CAShapeLayer *placeRLayer;
@property (nonatomic, strong) UIColor *placeColor;
@end

@implementation BezierView

/**
 画饼状图
 */
- (void)drawBieChart:(NSArray *)targetValues placeColor:(nonnull UIColor *)placeColor {
    self.placeColor = placeColor;
    //移除之前添加的子layer,避免重复添加
    while (self.layer.sublayers.count) {
        [self.layer.sublayers.lastObject removeFromSuperlayer];
    }
    //设置圆的原点、半径
    CGPoint point = CGPointMake(self.frame.size.width / 2.0, self.frame.size.height / 2.0);
    CGFloat startAngle = 1.5 * M_PI;    // 从十二点方向开始画
    CGFloat endAngle;
    CGFloat radius = self.frame.size.width / 2.0;
    
    //计算总数
    __block CGFloat allValues = 0;
    [targetValues enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        allValues += [obj floatValue];
    }];
    //画扇形图
    for (int i = 0; i < targetValues.count; i++) {
        CGFloat value = [targetValues[i] floatValue];
        endAngle = startAngle + value / allValues * 2 * M_PI;
        UIBezierPath * beiPath = [UIBezierPath bezierPathWithArcCenter:point
                                                                radius:radius
                                                            startAngle:startAngle
                                                              endAngle:endAngle
                                                             clockwise:YES];
        [beiPath addLineToPoint:point];
        [beiPath closePath];
        //渲染颜色
        CAShapeLayer * layer = [CAShapeLayer layer];
        layer.path = beiPath.CGPath;
        layer.lineWidth = 1;
        layer.strokeColor = UIColor.clearColor.CGColor;
        layer.fillColor = RandomColor.CGColor;
        [self.layer addSublayer:layer];
        
        //以上次终点为下次绘制的起点
        startAngle = endAngle;
    }
    
    CGFloat r = self.frame.size.width * 0.3;
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:point
                                                        radius:r
                                                    startAngle:0
                                                      endAngle:2 * M_PI
                                                     clockwise:YES];
    [path addLineToPoint:point];
    self.placeRLayer.path = path.CGPath;
    [self.layer addSublayer:self.placeRLayer];
    
}

- (CAShapeLayer *)placeRLayer{
    if (!_placeRLayer) {
        _placeRLayer = [CAShapeLayer layer];
        _placeRLayer.fillColor = self.placeColor.CGColor;
    }
    return _placeRLayer;
}

@end

在创建UIBezierPath对象的时候首先要确定它的中心点、半径大小、开始点、结束点,UIBezierPath对象创建完成后要将该对象的CGPath赋值给一个CAShapeLayer对象的path属性,并将CAShapeLayer对象添加到某个layer上。

创建UIBezierPath对象的bezierPathWithArcCenter方法最后一个属性clockwise代码是否需要顺时针。

三点钟方向为0(0度)和2M_PI(360度),6点钟方向为0.5M_PI(90度),9点钟方向为M_PI(180度),12点钟方向为1.5M_PI(270度),一圈360度=2M_PI。

上一篇 下一篇

猜你喜欢

热点阅读