Swift / UIView画出转速表

时间:2018-04-10 12:51:48

标签: swift uiview draw

我认为我正在进行大停电,但我无法简单地在Swift中使用BezierPaths。我想要做的就是截图: enter image description here

所以它就像一个有三种颜色的转速表:

我所拥有的是以下内容:

diagram.layer.borderWidth = 4.0
    diagram.layer.borderColor = UIColor.black.cgColor

    let pi = CGFloat(Float.pi)
    let start:CGFloat = 0.0
    let end :CGFloat = pi
    let radius : CGFloat = diagram.frame.width/3
    let middle = CGPoint(x: diagram.frame.size.width/2, y:diagram.frame.size.height/2)

    let path: UIBezierPath = UIBezierPath();
    path.addArc(
        withCenter: CGPoint(x: middle.x, y: middle.y),
        radius: radius,
        startAngle: start,
        endAngle: end,
        clockwise: false
    )

    let layer = CAShapeLayer()
    layer.fillColor = UIColor.clear.cgColor
    layer.strokeColor = UIColor.red.cgColor
    layer.path = path.cgPath
    diagram.layer.addSublayer(layer)

这只是第一个弧线,但它让我发疯。它没有居中,这很奇怪,因为我正在使用我的Uiview的大小。我的UIView显然被称为“图表”。

有没有人有一个很好的例子与Swift如何做截图上的事情? 谢谢你的阅读!

======= 这只是与andykkt

的答案有关的代码
func drawCompareGauge(frame: CGRect = CGRect(x: 0, y: 0, width: 180, height: 92), leftPercentage: CGFloat = 0.5) {
    //// General Declarations
    let context = UIGraphicsGetCurrentContext()

    //// Color Declarations
    let leftColor = UIColor(red: 0.278, green: 0.757, blue: 0.749, alpha: 1.000)
    let rightColor = UIColor(red: 0.557, green: 0.400, blue: 0.867, alpha: 1.000)

    //// Variable Declarations
    let leftDashed: CGFloat = 247 * leftPercentage

    //// rightRing Drawing
    let rightRingPath = UIBezierPath()
    rightRingPath.move(to: CGPoint(x: frame.minX + 11.5, y: frame.minY + 91.5))
    rightRingPath.addCurve(to: CGPoint(x: frame.minX + 42.73, y: frame.minY + 28.82), controlPoint1: CGPoint(x: frame.minX + 11.5, y: frame.minY + 65.89), controlPoint2: CGPoint(x: frame.minX + 23.76, y: frame.minY + 43.15))
    rightRingPath.addCurve(to: CGPoint(x: frame.minX + 90, y: frame.minY + 13), controlPoint1: CGPoint(x: frame.minX + 55.88, y: frame.minY + 18.89), controlPoint2: CGPoint(x: frame.minX + 72.25, y: frame.minY + 13))
    rightRingPath.addCurve(to: CGPoint(x: frame.minX + 168.5, y: frame.minY + 91.5), controlPoint1: CGPoint(x: frame.minX + 133.35, y: frame.minY + 13), controlPoint2: CGPoint(x: frame.minX + 168.5, y: frame.minY + 48.15))
    rightColor.setStroke()
    rightRingPath.lineWidth = 23
    context?.saveGState()
    //CGContextSetLineDash(context, 0, [247, 247], 2)
    //context!.setLineDash(phase: <#T##CGFloat#>, lengths: <#T##[CGFloat]#>)
    context?.setLineDash(phase: 0, lengths: [247,247])
    //problem
    rightRingPath.stroke()
    context?.restoreGState()


    //// leftRing Drawing
    let leftRingPath = UIBezierPath()
    leftRingPath.move(to: CGPoint(x: frame.minX + 11.5, y: frame.minY + 91.5))
    leftRingPath.addCurve(to: CGPoint(x: frame.minX + 42.73, y: frame.minY + 28.82), controlPoint1: CGPoint(x: frame.minX + 11.5, y: frame.minY + 65.89), controlPoint2: CGPoint(x: frame.minX + 23.76, y: frame.minY + 43.15))
    leftRingPath.addCurve(to: CGPoint(x: frame.minX + 90, y: frame.minY + 13), controlPoint1: CGPoint(x: frame.minX + 55.88, y: frame.minY + 18.89), controlPoint2: CGPoint(x: frame.minX + 72.25, y: frame.minY + 13))
    leftRingPath.addCurve(to: CGPoint(x: frame.minX + 168.5, y: frame.minY + 91.5), controlPoint1: CGPoint(x: frame.minX + 133.35, y: frame.minY + 13), controlPoint2: CGPoint(x: frame.minX + 168.5, y: frame.minY + 48.15))
    leftColor.setStroke()
    leftRingPath.lineWidth = 23
    context?.saveGState()
    //context!.setLineDash(context, 0, [leftDashed, 247], 2)
    //Problem
    context?.setLineDash(phase: 0, lengths: [leftDashed,247])
    leftRingPath.stroke()
    context?.restoreGState()


    //// Text Drawing
    let textRect = CGRect(x: frame.minX + 7, y: frame.minY + 74, width: 11, height: 21)
    let textTextContent = NSString(string: "L")
    let textStyle = NSMutableParagraphStyle()
    textStyle.alignment = .left

    let textFontAttributes = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: UIFont.systemFontSize), NSAttributedStringKey.foregroundColor: UIColor.white, NSAttributedStringKey.paragraphStyle: textStyle]

    let textTextHeight: CGFloat = textTextContent.boundingRect(with: CGSize(width: textRect.width, height: CGFloat.infinity), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: textFontAttributes, context: nil).size.height
    context?.saveGState()
    context?.clip(to: textRect)
    textTextContent.draw(in: CGRect(x: textRect.minX, y: textRect.minY + (textRect.height - textTextHeight) / 2, width: textRect.width, height: textTextHeight), withAttributes: textFontAttributes)
    context?.restoreGState()


    //// Text 2 Drawing
    let text2Rect = CGRect(x: frame.minX + 164, y: frame.minY + 76, width: 11, height: 17)
    let text2TextContent = NSString(string: "R")
    let text2Style = NSMutableParagraphStyle()
    text2Style.alignment = .left

    let text2FontAttributes = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: UIFont.systemFontSize), NSAttributedStringKey.foregroundColor: UIColor.white, NSAttributedStringKey.paragraphStyle: text2Style]

    let text2TextHeight: CGFloat = text2TextContent.boundingRect(with: CGSize(width: text2Rect.width, height: CGFloat.infinity), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: text2FontAttributes, context: nil).size.height
    context?.saveGState()
    context?.clip(to: text2Rect)
    //CGContextClipToRect(context!, text2Rect)
    text2TextContent.draw(in: CGRect(x: text2Rect.minX, y: text2Rect.minY + (text2Rect.height - text2TextHeight) / 2, width: text2Rect.width, height: text2TextHeight), withAttributes: text2FontAttributes)
    context?.restoreGState()
}

1 个答案:

答案 0 :(得分:1)

我从&#34; PaintCode&#34;例如,您可以使用paintcode绘制您想要的样子。

@IBDesignable class GaugeView: UIView {

@IBInspectable var leftPercentage: CGFloat = 0.708 {
    didSet {
        setNeedsDisplay()
    }
}

@IBInspectable var otherPercentage: CGFloat = 0.206 {
    didSet {
        setNeedsDisplay()
    }
}

override func draw(_ rect: CGRect) {
    // Drawing code
    drawCompareGauge(frame: bounds, leftPercentage: leftPercentage, otherPercentage: otherPercentage)
}

func drawCompareGauge(frame: CGRect = CGRect(x: 0, y: 0, width: 180, height: 92), leftPercentage: CGFloat = 0.708, otherPercentage: CGFloat = 0.206) {
    //// General Declarations
    guard let context = UIGraphicsGetCurrentContext() else { return }

    //// Color Declarations
    let leftColor = UIColor(red: 0.278, green: 0.757, blue: 0.749, alpha: 1.000)
    let rightColor = UIColor(red: 0.557, green: 0.400, blue: 0.867, alpha: 1.000)
    let otherColor = UIColor(red: 0.800, green: 0.320, blue: 0.320, alpha: 1.000)

    //// Variable Declarations
    let leftDashed: CGFloat = 247 * leftPercentage
    let otherDashed: CGFloat = 247 * otherPercentage

    //// rightRing Drawing
    let rightRingPath = UIBezierPath()
    rightRingPath.move(to: CGPoint(x: frame.minX + 11.5, y: frame.minY + 91.5))
    rightRingPath.addCurve(to: CGPoint(x: frame.minX + 42.73, y: frame.minY + 28.82), controlPoint1: CGPoint(x: frame.minX + 11.5, y: frame.minY + 65.89), controlPoint2: CGPoint(x: frame.minX + 23.76, y: frame.minY + 43.15))
    rightRingPath.addCurve(to: CGPoint(x: frame.minX + 90, y: frame.minY + 13), controlPoint1: CGPoint(x: frame.minX + 55.88, y: frame.minY + 18.89), controlPoint2: CGPoint(x: frame.minX + 72.25, y: frame.minY + 13))
    rightRingPath.addCurve(to: CGPoint(x: frame.minX + 168.5, y: frame.minY + 91.5), controlPoint1: CGPoint(x: frame.minX + 133.35, y: frame.minY + 13), controlPoint2: CGPoint(x: frame.minX + 168.5, y: frame.minY + 48.15))
    rightColor.setStroke()
    rightRingPath.lineWidth = 23
    context.saveGState()
    context.setLineDash(phase: 0, lengths: [247, 247])
    rightRingPath.stroke()
    context.restoreGState()


    //// leftRing Drawing
    let leftRingPath = UIBezierPath()
    leftRingPath.move(to: CGPoint(x: frame.minX + 11.5, y: frame.minY + 91.5))
    leftRingPath.addCurve(to: CGPoint(x: frame.minX + 42.73, y: frame.minY + 28.82), controlPoint1: CGPoint(x: frame.minX + 11.5, y: frame.minY + 65.89), controlPoint2: CGPoint(x: frame.minX + 23.76, y: frame.minY + 43.15))
    leftRingPath.addCurve(to: CGPoint(x: frame.minX + 90, y: frame.minY + 13), controlPoint1: CGPoint(x: frame.minX + 55.88, y: frame.minY + 18.89), controlPoint2: CGPoint(x: frame.minX + 72.25, y: frame.minY + 13))
    leftRingPath.addCurve(to: CGPoint(x: frame.minX + 168.5, y: frame.minY + 91.5), controlPoint1: CGPoint(x: frame.minX + 133.35, y: frame.minY + 13), controlPoint2: CGPoint(x: frame.minX + 168.5, y: frame.minY + 48.15))
    leftColor.setStroke()
    leftRingPath.lineWidth = 23
    context.saveGState()
    context.setLineDash(phase: 0, lengths: [leftDashed, 247])
    leftRingPath.stroke()
    context.restoreGState()


    //// leftRing 2 Drawing
    let leftRing2Path = UIBezierPath()
    leftRing2Path.move(to: CGPoint(x: frame.minX + 11.5, y: frame.minY + 91.5))
    leftRing2Path.addCurve(to: CGPoint(x: frame.minX + 42.73, y: frame.minY + 28.82), controlPoint1: CGPoint(x: frame.minX + 11.5, y: frame.minY + 65.89), controlPoint2: CGPoint(x: frame.minX + 23.76, y: frame.minY + 43.15))
    leftRing2Path.addCurve(to: CGPoint(x: frame.minX + 90, y: frame.minY + 13), controlPoint1: CGPoint(x: frame.minX + 55.88, y: frame.minY + 18.89), controlPoint2: CGPoint(x: frame.minX + 72.25, y: frame.minY + 13))
    leftRing2Path.addCurve(to: CGPoint(x: frame.minX + 168.5, y: frame.minY + 91.5), controlPoint1: CGPoint(x: frame.minX + 133.35, y: frame.minY + 13), controlPoint2: CGPoint(x: frame.minX + 168.5, y: frame.minY + 48.15))
    otherColor.setStroke()
    leftRing2Path.lineWidth = 23
    context.saveGState()
    context.setLineDash(phase: 0, lengths: [otherDashed, 247])
    leftRing2Path.stroke()
    context.restoreGState()
}

我已将代码更改为类并支持最新的xcode&amp;迅速。您可以在视图控制器上放置此视图以查看结果并更改leftPercentage动画规范。

==============================

我已更新代码以显示3个不同的值作为规格,我希望这可以帮助您弄清楚。请参阅下面的gif以了解此控制措施。

Gauge in action