只需将其分解为单独的步骤即可。
\n第一个问题是如何绘制单独的刻度线。
\n一种方法是使用 绘制四个笔画UIBezierPath:
事实证明,您可以跳过这两行,只需添加这两个圆弧,然后关闭路径,您\xe2\x80\x99就完成了。将为UIBezierPath您添加两条弧线之间的线。例如:
let startAngle: CGFloat = 2 * .pi * (CGFloat(i) - 0.2) / CGFloat(tickCount)\nlet endAngle: CGFloat = 2 * .pi * (CGFloat(i) + 0.2) / CGFloat(tickCount)\n\n// create path for individual tickmark\n\nlet path = UIBezierPath()\npath.addArc(withCenter: center, radius: outerRadius, startAngle: startAngle, endAngle: endAngle, clockwise: true)\npath.addArc(withCenter: center, radius: innerRadius, startAngle: endAngle, endAngle: startAngle, clockwise: false)\npath.close()\n\n// use that path in a `CAShapeLayer`\n\nlet shapeLayer = CAShapeLayer()\nshapeLayer.fillColor = \xe2\x80\xa6\nshapeLayer.strokeColor = UIColor.clear.cgColor\nshapeLayer.path = path.cgPath\n\n// add it to our view\xe2\x80\x99s `layer`\n\nview.layer.addSublayer(shapeLayer)\nRun Code Online (Sandbox Code Playgroud)\n对和i之间重复此操作,其中是,并且您有 90 个刻度线:0tickCounttickCount90
显然,可以使用您想要的任何颜色,将进度范围之外的颜色设置为灰色,等等。但希望这说明了如何使用UIBezierPath渲染两个弧并使用指定颜色填充每个刻度线的形状的基本思想。
例如:
\nclass CircularTickView: UIView {\n var progress: CGFloat = 0.7 { didSet { setNeedsLayout() } }\n\n private var shapeLayers: [CAShapeLayer] = []\n private let startHue: CGFloat = 0.33\n private let endHue: CGFloat = 0.66\n private let outOfBoundsColor: UIColor = .lightGray\n \n override func layoutSubviews() {\n super.layoutSubviews()\n \n shapeLayers.forEach { $0.removeFromSuperlayer() }\n shapeLayers = []\n \n let outerRadius = min(bounds.width, bounds.height) / 2\n let innerRadius = outerRadius * 0.7\n let center = CGPoint(x: bounds.midX, y: bounds.midY)\n let tickCount = 90\n \n for i in 0 ..< tickCount {\n let shapeLayer = CAShapeLayer()\n shapeLayer.fillColor = color(percent: CGFloat(i) / CGFloat(tickCount)).cgColor\n shapeLayer.strokeColor = UIColor.clear.cgColor\n \n let startAngle: CGFloat = 2 * .pi * (CGFloat(i) - 0.2) / CGFloat(tickCount)\n let endAngle: CGFloat = 2 * .pi * (CGFloat(i) + 0.2) / CGFloat(tickCount)\n \n let path = UIBezierPath()\n path.addArc(withCenter: center, radius: outerRadius, startAngle: startAngle, endAngle: endAngle, clockwise: true)\n path.addArc(withCenter: center, radius: innerRadius, startAngle: endAngle, endAngle: startAngle, clockwise: false)\n path.close()\n shapeLayer.path = path.cgPath\n \n layer.addSublayer(shapeLayer)\n shapeLayers.append(shapeLayer)\n }\n }\n\n private func color(percent: CGFloat) -> UIColor {\n if percent > progress {\n return outOfBoundsColor\n } \n \n let hue = (endHue - startHue) * percent + startHue\n return UIColor(hue: hue, saturation: 1, brightness: 1, alpha: 1)\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n显然,您需要根据需要进行调整。也许改变颜色算法。也许让它从 12 o\xe2\x80\x99clock 开始,而不是 3 o\xe2\x80\x99clock。等等。细节并不重要,重要的是了解如何添加带有 UI 路径的形状图层的基本思想。
\n虽然我更喜欢使用形状图层,但您也可以使用覆盖 的再现draw(_:):
class CircularTickView: UIView { \n var progress: CGFloat = 0.7 { didSet { setNeedsDisplay() } }\n\n private let startHue: CGFloat = 0.33\n private let endHue: CGFloat = 0.66\n private let outOfBoundsColor: UIColor = .lightGray\n \n override func draw(_ rect: CGRect) {\n super.draw(rect)\n \n let outerRadius = min(bounds.width, bounds.height) / 2\n let innerRadius = outerRadius * 0.7\n let center = CGPoint(x: bounds.midX, y: bounds.midY)\n let tickCount = 90\n \n for i in 0 ..< tickCount {\n let startAngle: CGFloat = 2 * .pi * (CGFloat(i) - 0.2) / CGFloat(tickCount)\n let endAngle: CGFloat = 2 * .pi * (CGFloat(i) + 0.2) / CGFloat(tickCount)\n \n let path = UIBezierPath()\n path.addArc(withCenter: center, radius: outerRadius, startAngle: startAngle, endAngle: endAngle, clockwise: true)\n path.addArc(withCenter: center, radius: innerRadius, startAngle: endAngle, endAngle: startAngle, clockwise: false)\n path.close()\n\n if path.cgPath.intersects(UIBezierPath(rect: rect).cgPath)) {\n color(percent: CGFloat(i) / CGFloat(tickCount))\n .setFill()\n path.fill() \n }\n }\n }\n\n private func color(percent: CGFloat) -> UIColor {\n if percent > progress {\n return outOfBoundsColor\n } \n \n let hue = (endHue - startHue) * percent + startHue\n return UIColor(hue: hue, saturation: 1, brightness: 1, alpha: 1)\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
948 次 |
| 最近记录: |