绘制带孔的pieChart

时间:2016-10-10 15:38:05

标签: ios objective-c

我有“饼图”图表,用UIBezierPath绘制。我想要的是,开始用偏移绘制它,以在圆圈内实现“洞”。现在它看起来像这样:

enter image description here

它创建了“切片”:

- (void)drawSliceOfPie:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle fillColor:(UIColor *)fillColor strokeColor:(UIColor *)strokeColor lineWidth:(CGFloat)lineWidth
{

    // Draw text


    //draw arc
    CGPoint center = CGPointMake(self.bounds.size.height / 2, self.bounds.size.width / 2);

    UIBezierPath *arc = [UIBezierPath bezierPath]; //empty path
    [arc setLineWidth:lineWidth];
    [arc moveToPoint:center];
    CGPoint next;
    next.x = center.x + radius * cos(startAngle);
    next.y = center.y + radius * sin(startAngle);
    [arc addLineToPoint:next]; //go one end of arc

    [arc addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES]; //add the arc
    [arc addLineToPoint:center]; //back to center

    // Draw text (new)
    float _x, _y, _nextX, _nextY;
    _nextX =center.x + radius/2 * cos(startAngle);
    _nextY =center.y + radius/2 * sin(startAngle);

    _x =_nextX + radius/2 * cos(endAngle);
    _y =_nextY + radius/2 * sin(endAngle);
    // x - 523, y - 472

    NSString *str = @"123";
    CGPoint halfCenter = CGPointMake(_x, _y);
    [str drawAtPoint:halfCenter withAttributes:nil];
    //

    [fillColor set];
    [arc fill];
    [strokeColor set];
    [arc stroke];
}

我只是想在其中实现“While hole”(不是在上面添加子视图,而是用偏移绘制它)。如何实现?

2 个答案:

答案 0 :(得分:2)

以下是使用UIBezierPath

整体绘制饼图的代码图

SWIFT版本: -

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.drawCircle(center: self.view.center, radius: 100, startAngle: 0, endAngle: CGFloat(M_PI * 0.8), color: UIColor.red)
        self.drawCircle(center: self.view.center, radius: 100, startAngle: CGFloat(M_PI * 0.8), endAngle: CGFloat(M_PI * 0.2), color: UIColor.green)
        self.drawCircle(center: self.view.center, radius: 100, startAngle: CGFloat(M_PI * 0.2), endAngle: CGFloat(M_PI * 0.0), color: UIColor.blue)

            }

    func drawCircle(center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle:CGFloat, color: UIColor) {

        let circlePath = UIBezierPath(arcCenter: center, radius: radius, startAngle: startAngle, endAngle:endAngle, clockwise: false)

        let shapeLayer = CAShapeLayer()
        shapeLayer.path = circlePath.cgPath

        //change the fill color
        shapeLayer.fillColor = UIColor.clear.cgColor
        //you can change the stroke color
        shapeLayer.strokeColor = color.cgColor
        //you can change the line width
        shapeLayer.lineWidth = 50.0

        view.layer.addSublayer(shapeLayer)

    }
}

目标C版: -

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self drawCircle:self.view.center radius:100 startAngle:0 endAngle:(M_PI * 0.8) color:[UIColor redColor]];
    [self drawCircle:self.view.center radius:100 startAngle:(M_PI * 0.8) endAngle:(M_PI * 0.2) color:[UIColor greenColor]];
    [self drawCircle:self.view.center radius:100 startAngle:(M_PI * 0.2) endAngle:(M_PI * 0.0) color:[UIColor blueColor]];
}


- (void) drawCircle:(CGPoint) center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle color:(UIColor *)color
{
    UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:false];
    CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
    shapeLayer.path = circlePath.CGPath;

    //change the fill color
    shapeLayer.fillColor = [[UIColor clearColor] CGColor];
    //you can change the stroke color
    shapeLayer.strokeColor = [color CGColor];
    //you can change the line width
    shapeLayer.lineWidth = 50.0;

    [self.view.layer addSublayer:shapeLayer];
}

答案 1 :(得分:2)

很好,我把它用于我的项目。

 extension CGFloat {
func radians() -> CGFloat {
    let b = CGFloat(M_PI) * (self/180)
    return b
}
}

 extension UIBezierPath {
convenience init(circleSegmentCenter center:CGPoint, radius:CGFloat, startAngle:CGFloat, endAngle:CGFloat)
{
    self.init()
    self.moveToPoint(CGPointMake(center.x, center.y))
    self.addArcWithCenter(center, radius:radius, startAngle:startAngle.radians(), endAngle: endAngle.radians(), clockwise:true)
    self.closePath()
}
}



  func pieChart(pieces:[(UIBezierPath, UIColor)], viewRect:CGRect) -> UIView {
var layers = [CAShapeLayer]()
for p in pieces {
    let layer = CAShapeLayer()
    layer.path = p.0.CGPath
    layer.fillColor = p.1.CGColor
    layer.strokeColor = UIColor.whiteColor().CGColor
    layers.append(layer)
}
let view = UIView(frame: viewRect)
for l in layers {

    view.layer.addSublayer(l)


}
return view
 }

 let rectSize = CGRectMake(0,0,400,400)
 let centrePointOfChart =      CGPointMake(CGRectGetMidX(rectSize),CGRectGetMidY(rectSize))
 let radius:CGFloat = 100
 let piePieces = [(UIBezierPath(circleSegmentCenter: centrePointOfChart, radius: radius, startAngle: 250, endAngle: 360),UIColor.brownColor()), (UIBezierPath(circleSegmentCenter: centrePointOfChart, radius: radius, startAngle: 0, endAngle: 200),UIColor.orangeColor()), (UIBezierPath(circleSegmentCenter: centrePointOfChart, radius: radius, startAngle: 200, endAngle: 250),UIColor.lightGrayColor())]
pieChart(piePieces, viewRect: CGRectMake(0,0,400,400))

取自:http://sketchytech.blogspot.com/2016/02/swift-going-round-in-semicircles-with.html

获取更多帮助:  https://github.com/vitorventurin/PieChartComponent  https://github.com/andjash/AYPieChart