iOS精品

iOS&swift绘制扇形图UIGraphicsGetCurre

2020-11-07  本文已影响0人  斐波那契程序员

一、获取上下文绘制图形只能在系统方法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)
    }

四、总结:其实挺简单的,主要是思路要清晰,不明白地方的欢迎大家在下发留言。

上一篇 下一篇

猜你喜欢

热点阅读