【发布时间】:2018-04-10 12:51:47
【问题描述】:
我想我有点停电了,但我不能简单地在 Swift 中使用 BezierPaths。想要我想做的就像在屏幕截图上一样:
所以它就像一个具有三种颜色的转速表:
我所拥有的如下:
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()
}
【问题讨论】:
-
与您的问题无关,但为什么不简单地
withCenter: middle和CGFloat.pi -
你说得对,我本来可以那样做的。谢谢:)
-
顺便说一句,您可以使用视图中心属性
diagram.center。path.addArc(withCenter: diagram.center, radius: diagram.frame.width / 4, startAngle: 0, endAngle: .pi, clockwise: false) -
您应该使用
bounds,而不是frame。视图的绘制不应根据视图在其父视图中的放置位置而改变。 -
其中一个选项是使用“PaintCode”之类的工具,您可以绘制和导出代码。