ios自定义View实现K线控件实例代码
时间: 2023-09-01 14:10:20 浏览: 215
下面是一个简单的 iOS 自定义 View 实现 K 线图的示例代码:
```swift
import UIKit
class KLineChartView: UIView {
// K线图数据
var data: [KLineChartData] = []
// K线图相关配置
var config: KLineChartConfig = KLineChartConfig()
// Y轴最大值
var yAxisMaxValue: CGFloat = 0
// Y轴最小值
var yAxisMinValue: CGFloat = 0
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext() else { return }
// 绘制背景色
context.setFillColor(config.backgroundColor.cgColor)
context.fill(rect)
// 计算 Y 轴最大值和最小值
calculateYAxisValue()
// 绘制 Y 轴
drawYAxis(context: context)
// 绘制 K 线图
drawKLineChart(context: context)
}
// 计算 Y 轴最大值和最小值
private func calculateYAxisValue() {
var maxValue: CGFloat = 0
var minValue: CGFloat = CGFloat.greatestFiniteMagnitude
for item in data {
if item.high > maxValue {
maxValue = item.high
}
if item.low < minValue {
minValue = item.low
}
}
yAxisMaxValue = maxValue
yAxisMinValue = minValue
}
// 绘制 Y 轴
private func drawYAxis(context: CGContext) {
context.setStrokeColor(config.yAxisColor.cgColor)
context.setLineWidth(config.yAxisLineWidth)
// 计算 Y 轴刻度值
let stepValue = (yAxisMaxValue - yAxisMinValue) / CGFloat(config.yAxisTickCount - 1)
for i in 0..<config.yAxisTickCount {
// 计算 Y 轴刻度值对应的坐标
let y = bounds.height - CGFloat(i) / CGFloat(config.yAxisTickCount - 1) * bounds.height
// 绘制 Y 轴刻度线
context.move(to: CGPoint(x: 0, y: y))
context.addLine(to: CGPoint(x: config.yAxisTickLength, y: y))
context.strokePath()
// 绘制 Y 轴刻度值
let textRect = CGRect(x: 0, y: y - config.yAxisTickTextSize / 2, width: config.yAxisTickTextSize, height: config.yAxisTickTextSize)
let text = String(format: "%.2f", yAxisMinValue + CGFloat(i) * stepValue)
let attributes: [NSAttributedString.Key: Any] = [.foregroundColor: config.yAxisTextColor, .font: UIFont.systemFont(ofSize: config.yAxisTickTextSize)]
let attributedText = NSAttributedString(string: text, attributes: attributes)
attributedText.draw(in: textRect)
}
}
// 绘制 K 线图
private func drawKLineChart(context: CGContext) {
let barWidth = bounds.width / CGFloat(data.count)
for (index, item) in data.enumerated() {
let x = CGFloat(index) * barWidth + barWidth / 2
let highY = bounds.height - (item.high - yAxisMinValue) / (yAxisMaxValue - yAxisMinValue) * bounds.height
let lowY = bounds.height - (item.low - yAxisMinValue) / (yAxisMaxValue - yAxisMinValue) * bounds.height
let openY = bounds.height - (item.open - yAxisMinValue) / (yAxisMaxValue - yAxisMinValue) * bounds.height
let closeY = bounds.height - (item.close - yAxisMinValue) / (yAxisMaxValue - yAxisMinValue) * bounds.height
// 绘制 K 线图
context.setStrokeColor(item.color.cgColor)
context.setLineWidth(config.kLineWidth)
context.move(to: CGPoint(x: x, y: highY))
context.addLine(to: CGPoint(x: x, y: lowY))
context.strokePath()
// 绘制 K 线实体
if item.close > item.open {
context.setFillColor(config.riseColor.cgColor)
} else {
context.setFillColor(config.fallColor.cgColor)
}
let bodyRect = CGRect(x: x - config.kLineBodyWidth / 2, y: min(openY, closeY), width: config.kLineBodyWidth, height: abs(openY - closeY))
context.fill(bodyRect)
}
}
}
// K线图数据结构体
struct KLineChartData {
var open: CGFloat = 0 // 开盘价
var close: CGFloat = 0 // 收盘价
var high: CGFloat = 0 // 最高价
var low: CGFloat = 0 // 最低价
var color: UIColor = .black // 颜色
}
// K线图配置
struct KLineChartConfig {
var backgroundColor: UIColor = .white // 背景色
var yAxisColor: UIColor = .black // Y轴颜色
var yAxisLineWidth: CGFloat = 1 // Y轴线宽
var yAxisTextColor: UIColor = .black // Y轴文本颜色
var yAxisTickTextSize: CGFloat = 10 // Y轴刻度值文本大小
var yAxisTickCount: Int = 5 // Y轴刻度值数量
var yAxisTickLength: CGFloat = 5 // Y轴刻度线长度
var kLineWidth: CGFloat = 1 // K线线宽
var kLineBodyWidth: CGFloat = 6 // K线实体宽度
var riseColor: UIColor = .red // 上涨颜色
var fallColor: UIColor = .green // 下跌颜色
}
```
使用方法:
```swift
let kLineChartView = KLineChartView(frame: CGRect(x: 0, y: 0, width: 300, height: 200))
kLineChartView.data = [
KLineChartData(open: 100, close: 120, high: 125, low: 95, color: .black),
KLineChartData(open: 120, close: 110, high: 135, low: 105, color: .black),
KLineChartData(open: 110, close: 130, high: 140, low: 100, color: .black),
KLineChartData(open: 130, close: 115, high: 145, low: 110, color: .black),
KLineChartData(open: 115, close: 125, high: 130, low: 105, color: .black),
KLineChartData(open: 125, close: 135, high: 140, low: 120, color: .black),
KLineChartData(open: 135, close: 120, high: 145, low: 115, color: .black),
]
kLineChartView.config.yAxisTickCount = 5
kLineChartView.config.kLineBodyWidth = 4
kLineChartView.config.riseColor = .red
kLineChartView.config.fallColor = .green
view.addSubview(kLineChartView)
```
阅读全文