UIView绘制圆弧型仪表图
UIView drawing an arc type gauge chart
我有一个仪表形状的图表,其中包含多个设计元素(见附件)。我正在努力解决的关键部分真的是用虚线得到一个像样的弧形。
到目前为止,我不确定我是应该走 Core Graphics 路线还是使用 UIKit 中的某些东西,即 UIBezierPath。
我已经在扩展 UIView 的 class 中尝试了这个,它给了我虚线,但弧线本身还不够好:
class Example: UIView {
override func drawRect(rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
CGContextSetLineWidth(context, 10.0)
CGContextSetStrokeColorWithColor(context, UIColor.greenColor().CGColor)
let dashArray:[CGFloat] = [1,10, 0, 0]
CGContextSetLineDash(context, 2, dashArray, 4)
CGContextMoveToPoint(context, 10, 200)
CGContextAddQuadCurveToPoint(context, 0, 0, 100, 200)
CGContextStrokePath(context)
}
}
然后还有一些其他方法可以使用 UIBezierPath 实现这一点,但我不确定我将如何在这里应用虚线...
获得虚线弧线的主要基础是我的主要目标 atm - 我相信一旦我得到这个我就能锻炼渐变和动画:)
任何帮助将不胜感激:)
你需要的是两条虚线宽度不同的贝塞尔曲线路径。
你可以从这里开始E:
T0 获得更高的破折号贝塞尔曲线:
UIBezierPath* oval2Path = [UIBezierPath bezierPathWithOvalInRect: yourRect];
[UIColor.redColor setStroke];
oval2Path.lineWidth = 13;
CGFloat oval2Pattern[] = {2, 20};
[oval2Path setLineDash: oval2Pattern count: 2 phase: 0];
[oval2Path stroke];
要获得小破折号贝塞尔曲线,您需要缩小破折号之间的距离:
UIBezierPath* ovalPath = [UIBezierPath bezierPathWithOvalInRect: yourRect];
[UIColor.redColor setStroke];
ovalPath.lineWidth = 6;
CGFloat ovalPattern[] = {2, 1};
[ovalPath setLineDash: ovalPattern count: 2 phase: 0];
[ovalPath stroke];
现在您可以将这两条贝塞尔曲线路径放在一起:
- (void)drawFrame: (CGRect)frame
{
// Oval Drawing
UIBezierPath* ovalPath = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(CGRectGetMinX(frame), CGRectGetMinY(frame), 70, 70)];
[UIColor.redColor setStroke];
ovalPath.lineWidth = 6;
CGFloat ovalPattern[] = {2, 1};
[ovalPath setLineDash: ovalPattern count: 2 phase: 0];
[ovalPath stroke];
// Oval 2 Drawing
UIBezierPath* oval2Path = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(CGRectGetMinX(frame) + 0.5, CGRectGetMinY(frame) - 0.5, 70, 70)];
[UIColor.redColor setStroke];
oval2Path.lineWidth = 13;
CGFloat oval2Pattern[] = {2, 20};
[oval2Path setLineDash: oval2Pattern count: 2 phase: 0];
[oval2Path stroke];
}
Swift:
func drawCanvas1(frame frame: CGRect = CGRect(x: 86, y: 26, width: 70, height: 70)) {
let context = UIGraphicsGetCurrentContext()
// Oval Drawing
let ovalPath = UIBezierPath(ovalInRect: CGRect(x: frame.minX, y: frame.minY, width: 70, height: 70))
UIColor.redColor().setStroke()
ovalPath.lineWidth = 6
CGContextSaveGState(context)
CGContextSetLineDash(context, 4.5, [0, 1], 2)
ovalPath.stroke()
CGContextRestoreGState(context)
// Oval 2 Drawing
let oval2Path = UIBezierPath(ovalInRect: CGRect(x: frame.minX + 0.5, y: frame.minY - 0.5, width: 70, height: 70))
UIColor.redColor().setStroke()
oval2Path.lineWidth = 13
CGContextSaveGState(context)
CGContextSetLineDash(context, 39, [1, 10], 2)
oval2Path.stroke()
CGContextRestoreGState(context)
}
类似地,您可以对圆弧采用相同的方法,只需将 bezierPathWithOval
方法替换为 bezierPathWithArcCenter
方法
请注意:
CGFloat ovalPattern[] = {2, 1};
//2 是 Dash 宽度,1 是 dash 之间的间隙
您可以调整这些值以提高准确性!
这是目前我能做的最好的翻译工作 UIBezierPath
。当我找到更好的方法时,我会更新我的代码。
// First Arc //
guageArcOne.path = UIBezierPath(arcCenter: centerPoint, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true).CGPath
guageArcOne.fillColor = UIColor.clearColor().CGColor
guageArcOne.strokeColor = UIColor.greenColor().CGColor
guageArcOne.lineWidth = 10.0
guageArcOne.strokeEnd = 1.0
guageArcOne.lineDashPattern = [1,10, 0, 0]
guageArcOne.lineDashPhase = 2.0
arcContainerView.layer.addSublayer(guageArcOne)
// Second Arc //
guageArcTwo.path = UIBezierPath(arcCenter: centerPoint, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true).CGPath
guageArcTwo.fillColor = UIColor.clearColor().CGColor
guageArcTwo.strokeColor = UIColor.greenColor().CGColor
guageArcTwo.lineWidth = 10.0
guageArcTwo.strokeEnd = 1.0
guageArcTwo.lineDashPattern = [1,2, 0, 0]
guageArcTwo.lineDashPhase = 2.0
arcContainerView.layer.addSublayer(guageArcTwo)
编辑:为更短、更频繁的破折号添加了第二个弧线。
我有一个仪表形状的图表,其中包含多个设计元素(见附件)。我正在努力解决的关键部分真的是用虚线得到一个像样的弧形。
到目前为止,我不确定我是应该走 Core Graphics 路线还是使用 UIKit 中的某些东西,即 UIBezierPath。
我已经在扩展 UIView 的 class 中尝试了这个,它给了我虚线,但弧线本身还不够好:
class Example: UIView {
override func drawRect(rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
CGContextSetLineWidth(context, 10.0)
CGContextSetStrokeColorWithColor(context, UIColor.greenColor().CGColor)
let dashArray:[CGFloat] = [1,10, 0, 0]
CGContextSetLineDash(context, 2, dashArray, 4)
CGContextMoveToPoint(context, 10, 200)
CGContextAddQuadCurveToPoint(context, 0, 0, 100, 200)
CGContextStrokePath(context)
}
}
然后还有一些其他方法可以使用 UIBezierPath 实现这一点,但我不确定我将如何在这里应用虚线...
获得虚线弧线的主要基础是我的主要目标 atm - 我相信一旦我得到这个我就能锻炼渐变和动画:)
任何帮助将不胜感激:)
你需要的是两条虚线宽度不同的贝塞尔曲线路径。
你可以从这里开始E:
T0 获得更高的破折号贝塞尔曲线:
UIBezierPath* oval2Path = [UIBezierPath bezierPathWithOvalInRect: yourRect];
[UIColor.redColor setStroke];
oval2Path.lineWidth = 13;
CGFloat oval2Pattern[] = {2, 20};
[oval2Path setLineDash: oval2Pattern count: 2 phase: 0];
[oval2Path stroke];
要获得小破折号贝塞尔曲线,您需要缩小破折号之间的距离:
UIBezierPath* ovalPath = [UIBezierPath bezierPathWithOvalInRect: yourRect];
[UIColor.redColor setStroke];
ovalPath.lineWidth = 6;
CGFloat ovalPattern[] = {2, 1};
[ovalPath setLineDash: ovalPattern count: 2 phase: 0];
[ovalPath stroke];
现在您可以将这两条贝塞尔曲线路径放在一起:
- (void)drawFrame: (CGRect)frame
{
// Oval Drawing
UIBezierPath* ovalPath = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(CGRectGetMinX(frame), CGRectGetMinY(frame), 70, 70)];
[UIColor.redColor setStroke];
ovalPath.lineWidth = 6;
CGFloat ovalPattern[] = {2, 1};
[ovalPath setLineDash: ovalPattern count: 2 phase: 0];
[ovalPath stroke];
// Oval 2 Drawing
UIBezierPath* oval2Path = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(CGRectGetMinX(frame) + 0.5, CGRectGetMinY(frame) - 0.5, 70, 70)];
[UIColor.redColor setStroke];
oval2Path.lineWidth = 13;
CGFloat oval2Pattern[] = {2, 20};
[oval2Path setLineDash: oval2Pattern count: 2 phase: 0];
[oval2Path stroke];
}
Swift:
func drawCanvas1(frame frame: CGRect = CGRect(x: 86, y: 26, width: 70, height: 70)) {
let context = UIGraphicsGetCurrentContext()
// Oval Drawing
let ovalPath = UIBezierPath(ovalInRect: CGRect(x: frame.minX, y: frame.minY, width: 70, height: 70))
UIColor.redColor().setStroke()
ovalPath.lineWidth = 6
CGContextSaveGState(context)
CGContextSetLineDash(context, 4.5, [0, 1], 2)
ovalPath.stroke()
CGContextRestoreGState(context)
// Oval 2 Drawing
let oval2Path = UIBezierPath(ovalInRect: CGRect(x: frame.minX + 0.5, y: frame.minY - 0.5, width: 70, height: 70))
UIColor.redColor().setStroke()
oval2Path.lineWidth = 13
CGContextSaveGState(context)
CGContextSetLineDash(context, 39, [1, 10], 2)
oval2Path.stroke()
CGContextRestoreGState(context)
}
类似地,您可以对圆弧采用相同的方法,只需将 bezierPathWithOval
方法替换为 bezierPathWithArcCenter
方法
请注意:
CGFloat ovalPattern[] = {2, 1};
//2 是 Dash 宽度,1 是 dash 之间的间隙
您可以调整这些值以提高准确性!
这是目前我能做的最好的翻译工作 UIBezierPath
。当我找到更好的方法时,我会更新我的代码。
// First Arc //
guageArcOne.path = UIBezierPath(arcCenter: centerPoint, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true).CGPath
guageArcOne.fillColor = UIColor.clearColor().CGColor
guageArcOne.strokeColor = UIColor.greenColor().CGColor
guageArcOne.lineWidth = 10.0
guageArcOne.strokeEnd = 1.0
guageArcOne.lineDashPattern = [1,10, 0, 0]
guageArcOne.lineDashPhase = 2.0
arcContainerView.layer.addSublayer(guageArcOne)
// Second Arc //
guageArcTwo.path = UIBezierPath(arcCenter: centerPoint, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true).CGPath
guageArcTwo.fillColor = UIColor.clearColor().CGColor
guageArcTwo.strokeColor = UIColor.greenColor().CGColor
guageArcTwo.lineWidth = 10.0
guageArcTwo.strokeEnd = 1.0
guageArcTwo.lineDashPattern = [1,2, 0, 0]
guageArcTwo.lineDashPhase = 2.0
arcContainerView.layer.addSublayer(guageArcTwo)
编辑:为更短、更频繁的破折号添加了第二个弧线。