在 iOS 中使用 Core Graphics 绘制 VU 表
Posted
技术标签:
【中文标题】在 iOS 中使用 Core Graphics 绘制 VU 表【英文标题】:Draw VU meter using Core Graphics in iOS 【发布时间】:2016-01-27 13:51:20 【问题描述】:我正在尝试使用 Core Graphics 绘制与此有些相似的图像:
我能够画出主弧,但我不明白,如何将弧划分为部分/在弧上绘制刻度?我当前绘制圆弧的代码是:
[path addArcWithCenter:point radius:radius startAngle:DEGREES_TO_RADIANS(specific_start_angle) endAngle:DEGREES_TO_RADIANS(specific_end_angle) clockwise:NO];
我尝试使用strokeWithBlendMode
,但我遇到了刻度或刻度位置的问题。
【问题讨论】:
贴出你目前拥有的代码 @originaluser2 目前我只是在使用[path addArcWithCenter:point radius:radius startAngle:DEGREES_TO_RADIANS(specific_start_angle) endAngle:DEGREES_TO_RADIANS(specific_end_angle) clockwise:NO];
绘制圆弧
在photoshop上画图,然后使用。这就是简单的解决方案。否则,您需要使用贝塞尔路径绘制弧线并利用其 dashes 属性
【参考方案1】:
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];
输出
完整项目:https://github.com/hamishknight/VU-Meter-Arc
【讨论】:
【参考方案2】:你可以用破折号画贝塞尔路径,像这样::
//// 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];
Else 你可以画多条贝塞尔路径,画成你想要的样子:
类似这样的:
对于小线:
UIBezierPath* bezier2Path = [UIBezierPath bezierPath];
[bezier2Path moveToPoint: CGPointMake(65, 45)];
[bezier2Path addLineToPoint: CGPointMake(75, 63)];
[UIColor.blackColor setStroke];
bezier2Path.lineWidth = 1.5;
[bezier2Path stroke];
【讨论】:
正如@originaluser2 所说,它会正常工作,最终我尝试了这个,但无法获得起点和终点。但是,您的解决方案也部分正确。 :) 谢谢!以上是关于在 iOS 中使用 Core Graphics 绘制 VU 表的主要内容,如果未能解决你的问题,请参考以下文章
iOS绘图—— UIBezierPath 和 Core Graphics
IOS开发——Core Graphics & Core Animation