一、获取上下文绘制图形只能在系统方法draw(_ rect: CGRect)中完成,刚刚这几天有这个需求,花一点时间记录一下,本文使用swift语言完成,完成效果如下:
66D51956-6A71-4867-B06A-8108B6306D19.png
二、直接上代码吧,首先创建一个文字数组以及label容器,可以增减数组内容
var labels = Array<UILabel>()
let titles = ["应收账款","应付账款","应缴税金","货币资金余额","净利润增长率","营业收入"]
draw(_ rect: CGRect)代码
override func draw(_ rect: CGRect) {
///移除视图上已有label
for label in self.labels {
label.removeFromSuperview()
}
var values = Array<Int>()
var sum = 0
///生成随机数
for _ in titles {
let rand = Int.random(in: 200...500)
values.append(rand)
sum += rand
}
///计算百分比
var percents = Array<CGFloat>()
for value in values {
percents.append(CGFloat(value) / CGFloat(sum))
}
let center = CGPoint.init(x: kScreenWidth / 2.0, y: (self.height - self.bottomView.height) / 2.0)
let radius = kScreenWidth / 2.0 / 1.8
let context = UIGraphicsGetCurrentContext()!
///折线半径
let radius2 = radius + 30.0
///label宽度不能超出屏幕
let width = kScreenWidth/2.0 - radius2
let height: CGFloat = 20.0
var index = 0
var startAngle:CGFloat = 0.0
for percent in percents {
let angle = CGFloat.pi * 2.0 * percent
let color = UIColor.init(red: CGFloat.random(in: 0.0...1.0), green: CGFloat.random(in: 0.0...1.0), blue: CGFloat.random(in: 0.0...1.0), alpha: 1.0)
///画扇形
context.move(to: center)
context.setFillColor(color.cgColor)
context.addArc(center: center, radius: CGFloat(radius), startAngle: startAngle, endAngle: startAngle + angle, clockwise: false)
context.fillPath()
///画折线
let halfAngle = startAngle + angle / 2.0
let point1 = self.getPoint(center: center, angle: halfAngle, radius: radius)
let point2 = self.getPoint(center: center, angle: halfAngle, radius: radius2)
let point3x = point1.x <= point2.x ? point2.x + width : point2.x - width
let point3 = CGPoint.init(x: point3x, y: point2.y)
context.move(to: point1)
context.addLines(between: [point1,point2,point3])
context.setStrokeColor((UIColor.lightGray.cgColor))
context.strokePath()
///值标签
let labelx = point1.x <= point2.x ? point2.x : point3.x
let label = UILabel.init(frame: CGRect.init(x:labelx, y: point2.y - height, width: width, height: height))
label.font = UIFont.systemFont(ofSize: 15)
label.textAlignment = .center
label.textColor = UIColor.gray
label.text = "¥" + String(values[index] * 100)
self.addSubview(label)
self.labels.append(label)
///文字标签
let textLabel = UILabel.init(frame: CGRect.init(x: 0, y: 0, width: width, height: 30))
textLabel.center = self.getPoint(center: center, angle: halfAngle, radius: radius - 30)
textLabel.font = UIFont.systemFont(ofSize: 10)
textLabel.textColor = .white
textLabel.textAlignment = .center
textLabel.numberOfLines = 0
textLabel.text = self.titles[index] + "\n" + String.init(format: "%.f%%", percent * 100.0)
textLabel.transform = CGAffineTransform.init(rotationAngle: halfAngle + CGFloat.pi / 2.0)
self.addSubview(textLabel)
self.labels.append(textLabel)
startAngle += angle
index += 1
}
let toolLabel = UILabel.init(frame: CGRect.init(x: 0, y: 0, width: radius, height: radius))
toolLabel.backgroundColor = UIColor.white
toolLabel.center = center
toolLabel.setCornerRadius(0)///自定义方法,设置圆角
self.addSubview(toolLabel)
self.labels.append(toolLabel)
}
三、自定义通过圆心、弧度、半径获取目标点CGPoint
func getPoint(center: CGPoint, angle: CGFloat, radius: CGFloat) -> CGPoint {
let x = center.x + cos(angle) * radius
let y = center.y + sin(angle) * radius
return CGPoint.init(x: x, y: y)
}
四、总结:其实挺简单的,主要是思路要清晰,不明白地方的欢迎大家在下发留言。
网友评论