UIView绘制弧型仪表图

时间:2016-05-16 14:43:23

标签: ios uiview core-graphics uibezierpath uigraphicscontext

我有一个图表的形状,它有多个设计元素(见附件)。我正在努力的关键部分是用虚线获得一个不错的圆弧形状。

到目前为止,我不确定是否应该使用Core Graphics路线或在UIKit中使用某些东西,即UIBezierPath。

我在扩展UIView的类中尝试了这个,它给了我虚线但是弧本身不够好:

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 - 我相信一旦我得到这个,我将能够锻炼渐变和动画:)

任何帮助将不胜感激:)

enter image description here

2 个答案:

答案 0 :(得分:4)

您需要的是两条具有不同短划线宽度的bezier路径。

你可以从她开始:

T0得到更高的冲刺贝塞尔:

enter image description here

UIBezierPath* oval2Path = [UIBezierPath bezierPathWithOvalInRect: yourRect];
[UIColor.redColor setStroke];
oval2Path.lineWidth = 13;
CGFloat oval2Pattern[] = {2, 20};
[oval2Path setLineDash: oval2Pattern count: 2 phase: 0];
[oval2Path stroke];

要获得小破折号图案贝塞尔曲线,您需要缩短破折号之间的差距:

enter image description here

UIBezierPath* ovalPath = [UIBezierPath bezierPathWithOvalInRect: yourRect];
[UIColor.redColor setStroke];
ovalPath.lineWidth = 6;
CGFloat ovalPattern[] = {2, 1};   
[ovalPath setLineDash: ovalPattern count: 2 phase: 0];
[ovalPath stroke];

现在你可以将这两条bezier路径放在一起:

enter image description here

- (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];
}

夫特:

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是破折号之间的间隙

您可以调整这些值以确保准确性!

答案 1 :(得分:0)

目前,我可以将此转换为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)

编辑:为更短,更频繁的破折号添加了第二个弧。