具有多个弧的UIBezierPath

时间:2014-02-03 17:21:47

标签: ios objective-c ios7 uibezierpath

Hiiii

我正在尝试在视图中绘制具有动态宽度的弧。 enter image description here

我用几个带有弧线的UIBezierPath构建了一个ARRAY,然后我一个接一个地绘制。这是代码:

    - (void)drawRect:(CGRect)rect
    {
    // Drawing code

    CGFloat radious;
    if (self.bounds.size.width < self.bounds.size.height) {
        radious = self.bounds.size.width / 2;
    }
    else{
        radious = self.bounds.size.height / 2;
    }

    float oneGradeInRadians = (float)(2 * M_PI) / 360.f;
    float radiandToDraw = (float)self.finalAngleRadians - self.initialAngleRadians;
    float splitMeasure = oneGradeInRadians;
    int numberOfArcs = radiandToDraw / splitMeasure;

    NSMutableArray *arrayOfBeziersPaths = [NSMutableArray arrayWithCapacity:numberOfArcs];
    for (int i = 0; i < numberOfArcs; i++) {

         float startAngle = self.initialAngleRadians + (i * splitMeasure);
         float endAngle = self.initialAngleRadians +((i + 1) * splitMeasure);
         UIBezierPath *bezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.frame.size.width/2, self.frame.size.height/2) radius:radious - self.widthLine.floatValue startAngle:startAngle endAngle:endAngle clockwise:YES];
        bezierPath.lineWidth = self.widthLine.floatValue + i/20;
        float hue = (float)(i / 3.f);
        UIColor *color = [UIColor colorWithHue:hue/360.0 saturation:1 brightness:1 alpha:1];
        [color setStroke];

        [arrayOfBeziersPaths addObject:bezierPath];
    }



    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetLineJoin(context, kCGLineJoinMiter);
    //We saved the context
    CGContextSaveGState(context);
    for (int i = 0; i < numberOfArcs; i++) {
        [(UIBezierPath *)[arrayOfBeziersPaths objectAtIndex:i] stroke];
        [(UIBezierPath *)[arrayOfBeziersPaths objectAtIndex:i] fill];
     }

    //Restore the contex
    CGContextRestoreGState(context);
    }

通过这种方式,我获得了正确的形状,但是我也在弧之间产生了恼人的线条: enter image description here

我认为问题可能是在弧之间改变的属性,但我完全迷失了,或者可能还有另一种更好的方法来构建它。

我尝试创建了几个UIBezierPath路径,然后将它们添加到一个唯一的UIBezierPath中,然后我进行了stoke并填充了该路径。我没有得到恼人的线条,但问题是我无法修改线宽,所以我无法得到同样的效果。

有什么想法吗?感谢

2 个答案:

答案 0 :(得分:4)

不要创建许多这样的路径。只需创建加入两端的two arcs (inner circle, exterior circle)two straight行。然后填补路径。

在空viewController的viewDidLoad中添加以下代码并检查。

- (void)viewDidLoad
{
    [super viewDidLoad];

    CGFloat k =0.5522847498;
    UIBezierPath *path =[UIBezierPath bezierPath];
    CGFloat radius=130;
    [path addArcWithCenter:CGPointMake(0, 0) radius:radius startAngle:M_PI_2 endAngle:M_PI clockwise:NO];

    CGFloat start=10;
    CGFloat increment=5;
    [path addLineToPoint:CGPointMake(-radius-start, 0)];
    [path addCurveToPoint:CGPointMake(0, -radius-start-increment) controlPoint1:CGPointMake(-radius-start, -(radius +start)*k) controlPoint2:CGPointMake(-(radius+start)*k, -radius-start-increment)];
    [path addCurveToPoint:CGPointMake(radius+start+2*increment, 0) controlPoint1:CGPointMake((radius+start+increment)*k, -radius-start-increment) controlPoint2:CGPointMake(radius+start+2*increment, (-radius-start-increment)*k)];
    [path addCurveToPoint:CGPointMake(0, radius+start+3*increment) controlPoint1:CGPointMake(radius+start+2*increment, (radius+start+2*increment)*k) controlPoint2:CGPointMake((radius+start+2*increment)*k,radius+start+3*increment)];
    [path addLineToPoint:CGPointMake(0,radius)];

    CAShapeLayer *layer =[CAShapeLayer layer];
    [layer setFrame:CGRectMake(150, 200, 300, 300)];
    [layer setFillColor:[UIColor greenColor].CGColor];
    [layer setStrokeColor:[UIColor blackColor].CGColor];
    [layer setPath:path.CGPath];
    [self.view.layer addSublayer:layer];
}

它产生的结果如, enter image description here

答案 1 :(得分:1)

这里的问题是你选择了一种疯狂的方法来绘制你所追求的形状。如果你看一下它,你会发现它实际上是一个填充区域,在外面用圆弧限定,在内边缘用螺旋线。

因此,你应该做的是创建一个NSBezierPath,向它添加外圆弧,然后在螺旋的开头添加一条线,附加一个螺旋(你想要近似它)与Bézier段)并最终致电-closePath。在那之后,你可以-fill路径,你将得到一个好看的结果,而不是你上面的混乱。