![](https://img.haomeiwen.com/i6869621/e6c3e9484f8ba8cf.jpeg)
图片如上,要做成这样肯定不是一步完成了,咱来分段进行......(其实也就是各种贝塞尔曲线)
第一步,我们先画圆:
///画圆,这部分是UIView的扩展,包括下面任何一个方法都是UIView的扩展
func createCircel(radius:CGFloat){
let linePath = UIBezierPath(arcCenter: CGPoint(x: self.width/2, y: self.height/2), radius: radius, startAngle: 0, endAngle: CGFloat(Double.pi)*2, clockwise: false)
linePath.close()
//设施路径画布
let lineShape = CAShapeLayer()
lineShape.frame = CGRect(x: 0, y: 0, width: self.width, height: self.height)
//宽度
lineShape.lineWidth = 1
//路径颜色
lineShape.strokeColor = UIColor.grayValue(value: 222).cgColor
//获取贝塞尔曲线的路径
lineShape.path = linePath.cgPath
//填充色
lineShape.fillColor = UIColor.clear.cgColor
//把绘制的图放到layer上
self.layer.addSublayer(lineShape)
}
用此方法在view图层画圆,一般有多个,为了区分值多少,分值一般取0-10
第二步,画三根对边线,难点在于计算x和y值,涉及到三角函数,不过这次短边是斜边的一半长度,比较容易计算
func createLine(lenght:CGFloat){
let coreLong:(CGFloat,CGFloat) = calculateLong(lenght)
let centerX:CGFloat = self.width/2
let centerY:CGFloat = self.height/2
///第一象限的点
let areaOnePoint:CGPoint = CGPoint(x: centerX+coreLong.1, y: centerY-coreLong.0)
///第二象限的点
let areaTwoPoint:CGPoint = CGPoint(x: centerX-coreLong.1, y: centerY-coreLong.0)
///第三象限的点
let areaThreePoint:CGPoint = CGPoint(x: centerX-coreLong.1, y: centerY+coreLong.0)
///第四象限的点
let areaFourPoint:CGPoint = CGPoint(x: centerX+coreLong.1, y: centerY+coreLong.0)
let yOnePoint:CGPoint = CGPoint(x: centerX, y: centerY-lenght)
let yTwoPoint:CGPoint = CGPoint(x: centerX, y: centerY+lenght)
let linePath1 = UIBezierPath()
linePath1.move(to: areaOnePoint)
linePath1.addLine(to: areaThreePoint)
linePath1.close()
addToView(bez: linePath1,lineColor: UIColor.grayValue(value: 222))
let linePath2 = UIBezierPath()
linePath2.move(to: areaTwoPoint)
linePath2.addLine(to: areaFourPoint)
linePath2.close()
addToView(bez: linePath2,lineColor: UIColor.grayValue(value: 222))
let linePath3 = UIBezierPath()
linePath3.move(to: yOnePoint)
linePath3.addLine(to: yTwoPoint)
linePath3.close()
addToView(bez: linePath3,lineColor: UIColor.grayValue(value: 222))
}
private func addToView(bez:UIBezierPath,lineColor:UIColor){
let lineShape = CAShapeLayer()
lineShape.frame = CGRect(x: 0, y: 0, width: self.width, height: self.height)
//宽度
lineShape.lineWidth = 1
//路径颜色
lineShape.strokeColor = lineColor.cgColor
//获取贝塞尔曲线的路径
lineShape.path = bez.cgPath
//填充色
lineShape.fillColor = UIColor.init(r: 8, g: 136, b: 255, alpha: 0.3).cgColor
//把绘制的图放到layer上
self.layer.addSublayer(lineShape)
}
第三步,添加统计图
/// 添加统计图
///
/// - Parameters:
/// - counts: 顺时针添加的统计数据:比如 [1~10]
/// - full: 总长度 10
/// - height: 最大圆半径
func createCountView(counts:[CGFloat],full:CGFloat,height:CGFloat){
let centerX:CGFloat = self.width/2
let centerY:CGFloat = self.height/2
let oneLong:CGFloat = counts[0]/full*height
let twoLong:CGFloat = counts[1]/full*height
let threeLong:CGFloat = counts[2]/full*height
let fourLong:CGFloat = counts[3]/full*height
let fiveLong:CGFloat = counts[4]/full*height
let sixLong:CGFloat = counts[5]/full*height
let linePath = UIBezierPath()
linePath.move(to: CGPoint(x: centerX, y: centerY-oneLong))
linePath.addLine(to: CGPoint(x: centerX+calculateLong(twoLong).1, y: centerY-calculateLong(twoLong).0))
linePath.addLine(to: CGPoint(x: centerX+calculateLong(threeLong).1, y: centerY+calculateLong(threeLong).0))
linePath.addLine(to: CGPoint(x: centerX, y: centerY+fourLong))
linePath.addLine(to: CGPoint(x: centerX-calculateLong(fiveLong).1, y: centerY+calculateLong(fiveLong).0))
linePath.addLine(to: CGPoint(x: centerX-calculateLong(sixLong).1, y: centerY-calculateLong(sixLong).0))
linePath.close()
addToView(bez:linePath,lineColor: UIColor.clear)
}
/// 计算直角三角形两边长度(此图为60度角,计算比较容易,可以考虑用三角函数)
///
/// - Parameter long: 斜边长度
/// - Returns: (1:短,2:长)
private func calculateLong(_ long:CGFloat)->(CGFloat,CGFloat){
return (long/2,sqrt(long*long-(long/2)*(long/2)))
}
具体用法:
func formatView(){
var maxNum:Int = 0
var numbers:[CGFloat] = []
for (index,item) in dataArray.enumerated(){
if maxNum < item.num ?? 0{
maxNum = item.num ?? 0
}
numbers.append(CGFloat(item.num ?? 0))
}
let maxWidth:CGFloat = (centerView?.width ?? 0)/2 //除以2获得半径
let subWidth:CGFloat = maxWidth/5 //最大数分5份
for item in 1...5{ //1..5,分段画圈
centerView?.createCircel(radius: CGFloat(item)*subWidth)
}
centerView?.createLine(lenght: maxWidth)
centerView?.createCountView(counts: numbers, full: CGFloat(maxNum), height: maxWidth)
}
网友评论