使用iOS中的Core Graphics绘制VU表

时间:2016-01-27 13:51:21

标签: ios objective-c core-graphics

我正在尝试使用Core Graphics绘制一个类似的图像:

enter image description here

我能够绘制主弧,但我无法理解,如何将弧分成零件/在弧上绘制刻度?我当前绘制弧的代码是:

[path addArcWithCenter:point radius:radius startAngle:DEGREES_TO_RADIANS(specific_start_angle) endAngle:DEGREES_TO_RADIANS(specific_end_angle) clockwise:NO];

我尝试使用strokeWithBlendMode,但我面临着毕业或蜱的位置问题。

2 个答案:

答案 0 :(得分:5)

Teja's solution will work fine for you,但它确实需要您为毕业计算自己的起点和终点。

我建议您创建一个函数,让您在弧的给定角度绘制刻度,这将计算刻度的起点和终点,给定长度。

static inline void drawGraduation(CGPoint center, CGFloat radius, CGFloat angle, CGFloat length, CGFloat width, CGColorRef color) {

    CGContextRef c = UIGraphicsGetCurrentContext();

    CGFloat radius2 = radius+length; // The radius of the end points of the graduations
    CGPoint p1 = (CGPoint){cos(angle)*radius+center.x, sin(angle)*radius+center.y}; // the start point of the graduation
    CGPoint p2 = (CGPoint){cos(angle)*radius2+center.x, sin(angle)*radius2+center.y}; // the end point of the graduation

    CGContextMoveToPoint(c, p1.x, p1.y);
    CGContextAddLineToPoint(c, p2.x, p2.y);

    CGContextSetStrokeColorWithColor(c, color);
    CGContextSetLineWidth(c, width);

    CGContextStrokePath(c);
}

然后,当您为VU表的主刻度绘制弧时,可以在for循环(或者您想要这样做)中调用它。您还可以按给定的时间间隔轻松自定义给定刻度的颜色,宽度和长度(例如,此代码每5次刻度会产生更粗和更长的红线)。

- (void)drawRect:(CGRect)rect {

    CGRect r = self.bounds;

    CGFloat startAngle = -M_PI*0.2; // start angle of the main arc
    CGFloat endAngle = -M_PI*0.8; // end angle of the main arc

    NSUInteger numberOfGraduations = 16;
    CGPoint center = (CGPoint){r.size.width*0.5, r.size.height*0.5}; // center of arc
    CGFloat radius = (r.size.width*0.5)-20; // radius of arc

    CGFloat maxGraduationWidth = 1.5; // the maximum graduation width
    CGFloat maxGraduationWidthAngle = maxGraduationWidth/radius; // the maximum graduation width angle (used to prevent the graduations from being stroked outside of the main arc)

    // draw graduations
    CGFloat deltaArc = (endAngle-startAngle+maxGraduationWidthAngle)/(numberOfGraduations-1); // the change in angle of the arc
    CGFloat startArc = startAngle-(maxGraduationWidthAngle*0.5); // the starting angle of the arc

    for (int i = 0; i < numberOfGraduations; i++) {
        if (i % 5 == 0) {
            drawGraduation(center, radius, startArc+(i*deltaArc), 14, 1.5, [UIColor redColor].CGColor); // red graduation every 5 graduations.
        } else {
            drawGraduation(center, radius, startArc+(i*deltaArc), 10, 1, [UIColor blackColor].CGColor);
        }

    }

    // draw main arc
    UIBezierPath* mainArc = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:NO];
    [[UIColor blackColor] setStroke];
    mainArc.lineWidth = 2;
    [mainArc stroke];

}

输出

enter image description here

完整项目:https://github.com/hamishknight/VU-Meter-Arc

答案 1 :(得分:3)

您可以使用短划线绘制bezier路径,如下所示:enter image description here

   //// Bezier Drawing
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint: CGPointMake(54.5, 62.5)];
[bezierPath addCurveToPoint: CGPointMake(121.5, 39.5) controlPoint1: CGPointMake(54.5, 62.5) controlPoint2: CGPointMake(87.5, 39.5)];
[bezierPath addCurveToPoint: CGPointMake(190.5, 62.5) controlPoint1: CGPointMake(155.5, 39.5) controlPoint2: CGPointMake(190.5, 62.5)];
[UIColor.blackColor setStroke];
bezierPath.lineWidth = 10;
CGFloat bezierPattern[] = {24, 2};
[bezierPath setLineDash: bezierPattern count: 2 phase: 0];
[bezierPath stroke];

否则您可以绘制多个贝塞尔曲线路径并将其绘制为类似于您想要的路径:

这样的事情:

enter image description here

对于小行:

UIBezierPath* bezier2Path = [UIBezierPath bezierPath];
[bezier2Path moveToPoint: CGPointMake(65, 45)];
[bezier2Path addLineToPoint: CGPointMake(75, 63)];
[UIColor.blackColor setStroke];
bezier2Path.lineWidth = 1.5;
[bezier2Path stroke];