使用UIBezierPath绘制弧段

时间:2015-05-26 19:10:05

标签: ios objective-c geometry calayer uibezierpath

我知道有很多与-(void)createCircleWithStartAngle:(int)startAngle endAngle:(int)endAngle name:(NSString *)name{ UIView *subView=_viewContainer; // Set up the shape of the circle int radius = 125; CAShapeLayer *circle = [CAShapeLayer layer]; // Make a circular shape UIBezierPath *path=[UIBezierPath bezierPathWithArcCenter:CGPointMake(radius, radius) radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES]; circle.path = [path CGPath]; // Center the shape in self.view circle.position = CGPointMake(CGRectGetMidX(subView.bounds)-radius, CGRectGetMidY(subView.bounds)-radius); circle.fillColor = [UIColor clearColor].CGColor; //making line end cap round circle.lineCap=kCALineCapRound; UIColor *strokeColor; if([name isEqualToString:@"A"]) strokeColor=[UIColor darkGrayColor]; else if([name isEqualToString:@"B"]) strokeColor=[UIColor colorWithRed:40.0/255.0 green:180.0/255.0 blue:213.0/255.0 alpha:1.0]; else if([name isEqualToString:@"C"]) strokeColor=[UIColor colorWithRed:240/255.0 green:240/255.0 blue:240/255.0 alpha:1.0]; circle.strokeColor = strokeColor.CGColor; circle.lineWidth = 10; // Add to parent layer [subView.layer addSublayer:circle]; // Configure animation CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; drawAnimation.duration = 1.0; drawAnimation.repeatCount = 1.0; drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f]; drawAnimation.toValue = [NSNumber numberWithFloat:1.0f]; drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; // Add the animation to the circle [circle addAnimation:drawAnimation forKey:@"drawCircleAnimation"]; } 有关的例子,但是我对用于绘制弧线的角度非常困惑,我的要求就像下面的图像一样绘制弧线。长度和角度应按总数计算。

enter image description here

现在我已经创建了一个绘制弧线的函数,见下文

    float angleToStart=DEGREES_TO_RADIANS(120);
    float angleToEnd=DEGREES_TO_RADIANS(270);
    //investment
    [self createCircleWithStartAngle:angleToStart endAngle:angleToEnd name:@"A"];



    float factor=total/bvalue;
    angleToStart=angleToEnd;
    angleToEnd=180/factor;
    angleToEnd=DEGREES_TO_RADIANS(angleToEnd);

    [self createCircleWithStartAngle:angleToStart endAngle:angleToEnd name:@"B"];



    angleToStart=DEGREES_TO_RADIANS(angleToEnd);
    angleToEnd=DEGREES_TO_RADIANS(60);
    [self createCircleWithStartAngle:angleToStart endAngle:angleToEnd name:@"C"];

我调用上面的函数3次,因此它创建了3个弧段,如下所示

-(void)createCircleWithStartAngle:(float)startAngle endAngle:(float)endAngle chartSection:(ChartSection)section lineCap:(NSString *const)lineCap{

    UIView *subView=_circleView;

    // Set up the shape of the circle
    float radius = _circleView.bounds.size.width/2.0;//125.0;

    CAShapeLayer *circle = [CAShapeLayer layer];
    // Make a circular shape

    UIBezierPath *path=[UIBezierPath bezierPathWithArcCenter:CGPointMake(radius, radius) radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];



    circle.path = [path CGPath];


    // Center the shape in self.view
    circle.position = CGPointMake(CGRectGetMidX(subView.bounds)-radius,
                                  CGRectGetMidY(subView.bounds)-radius);

    // Configure the apperence of the circle
    circle.fillColor = [UIColor clearColor].CGColor;


    UIColor *strokeColor;

    circle.lineCap=lineCap;

    switch (section) {
        case ChartSectionA:
            strokeColor=[UIColor darkGrayColor];
            break;
        case ChartSectionB:
            strokeColor=[UIColor colorWithRed:40.0/255.0 green:180.0/255.0 blue:213.0/255.0 alpha:1.0];
            break;
        case ChartSectionC:
            strokeColor=[UIColor colorWithRed:240/255.0 green:240/255.0 blue:240/255.0 alpha:1.0];
            break;
        default:
            strokeColor=[UIColor colorWithRed:40.0/255.0 green:180.0/255.0 blue:213.0/255.0 alpha:1.0];
            break;
    }



    circle.strokeColor = strokeColor.CGColor;
    circle.lineWidth = 10;

    //keep the arrangement intact with the indexes..
    [subView.layer insertSublayer:circle atIndex:section];



    // Configure animation
    CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    drawAnimation.duration            = 1.0;
    drawAnimation.repeatCount         = 1.0;

    // Animate from no part of the stroke being drawn to the entire stroke being drawn
    drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
    drawAnimation.toValue   = [NSNumber numberWithFloat:1.0f];

    // Experiment with timing to get the appearence to look the way you want
    drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

    // Add the animation to the circle
    [circle addAnimation:drawAnimation forKey:@"drawCircleAnimation"];
}

因此我得到如下的输出

enter image description here

这是某种方式正确,但不是100%,方案如下

  1. 深灰色的起点与终点白色
  2. 不同
  3. 深灰色部分应该总是半圈,而蓝色应该跟着因子。
  4. off white 分段,将剩余部分填充到最后。
  5. 任何人都可以帮助我获得正确的价值吗?所以它绘制了

    感谢。

    更新(添加完整的解决方案以绘制类似的弧线)

    下面的函数负责为提供的角度绘制弧

    -(void)createArcWithValueOfSectionA:(float)amountA sectionB:(float)amountB sectionC:(float)amountC{
    
        if(amountA<0.0)
            amountA=0.0;
    
        if(amountB<0.0)
            amountB=0.0;
    
        if(amountC<0.0)
            amountC=0.0;
    
    
        float baseStartAngle=120.0;//base start angle
        float baseEndAngle=60.0;//base end angle
        float totalAngle=300.0;//total angle to be calculated
    
        float sectionAPercent = amountA/(amountA+amountB+amountC);
        float sectionBPercent = amountB/(amountA+amountB+amountC);
    
    
        float angleToStart=DEGREES_TO_RADIANS(baseStartAngle);
        float angleToEnd=0.0;
    
        if(sectionAPercent<0)
            sectionAPercent=0.0;
    
        if(sectionBPercent<0)
            sectionBPercent=0.0;
    
    
        //calculate sectionA end angle with the value inputted
        angleToEnd=baseStartAngle + sectionAPercent * totalAngle;
    
        //we need to determine cap style as per data
        NSString *lineCap=kCALineCapRound;
    
    
    
        //Section A
        [self createCircleWithStartAngle:angleToStart endAngle:DEGREES_TO_RADIANS(angleToEnd) chartSection:ChartSectionA lineCap:lineCap];
    
    
        //next drawing for bidding should start from investment end angle
        angleToStart=angleToEnd;
    
        angleToEnd=sectionBPercent * totalAngle;
    
        angleToEnd=angleToStart+angleToEnd;
    
        lineCap=kCALineCapSquare;
    
        //Section B
        [self createCircleWithStartAngle:DEGREES_TO_RADIANS(angleToStart) endAngle:DEGREES_TO_RADIANS(angleToEnd) chartSection:ChartSectionB lineCap:lineCap];
    
        //next drawing for sectionC should start from sectionB end angle
        angleToStart=angleToEnd;
    
    
        lineCap=kCALineCapRound;
    
        //draw Section C amount till end
        angleToEnd=DEGREES_TO_RADIANS(baseEndAngle);
        [self createCircleWithStartAngle:DEGREES_TO_RADIANS(angleToStart) endAngle:angleToEnd chartSection:ChartSectionC lineCap:lineCap];
    
    }
    

    下面的函数根据值和上面的函数计算角度..

    {{1}}

    希望它有所帮助。

1 个答案:

答案 0 :(得分:5)

问题在于你为角度使用整数,但是你正在处理弧度:

- (void)createCircleWithStartAngle:(int)startAngle endAngle:(int)endAngle name:(NSString *)name;

为您的角度使用浮点(例如CGFloat)。