【问题标题】:UIView drawing an arc type gauge chartUIView 绘制圆弧型仪表图
【发布时间】:2016-09-12 09:42:28
【问题描述】:

我有一个仪表盘形状的图表,其中包含多个设计元素(见附件)。我正在努力解决的关键部分真的是用虚线得到一个体面的弧形。

到目前为止,我不确定我是否应该采用 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 - 我确信一旦我得到这个,我就能够锻炼渐变和动画:)

任何帮助将不胜感激:)

【问题讨论】:

    标签: ios uiview core-graphics uibezierpath uigraphicscontext


    【解决方案1】:

    您需要的是两条虚线宽度不同的贝塞尔路径。

    你可以从这里开始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];
    }
    

    斯威夫特:

    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 是短划线宽度,1 是短划线之间的间隙

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

    【讨论】:

    • 这其实很聪明。我不知道我会想到它。
    • 您可以使用绘制代码工具在贝塞尔路径上进行多种组合!你应该试一试@GlennHowes
    • 哇,感谢@TejaNandamuri - 为你的努力投了赞成票!如果可行,将检查一下:)
    【解决方案2】:

    这是目前我能做的最好的将其转换为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)
    

    编辑:为更短、更频繁的破折号添加了第二条弧线。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多