swift3.0 圆环

最近公司新项目要用swift做ios,产品图上有个显示体重的圆环。刚学不久实在是不会写。于是找了几个用swift写的仪表盘稍作修改。先来一张效果图:




代码:

import UIKit
extension UIViewController {
    var bounds : CGRect {
        get {
            return view.bounds
        }
    }
}

extension UIColor {
    class func CG_COLOR(颜色数组 values : Array<CGFloat>) -> CGColor {
        let r = values[0]
        let g = values[1]
        let b = values[2]
        let a = values[3]
        return UIColor.init(red: r, green: g, blue: b, alpha: a).cgColor
    }
}

class TestViewController: UIViewController {
    var progressLayer : CAShapeLayer?
    var progressLayer1 : CAShapeLayer?
    //体重
    var aLabel : UILabel?
    //kg
    var kgLabel : UILabel?
    //BMI
    var BMILabel : UILabel?
    var needleLayer : CAShapeLayer?
    override func viewDidLoad() {
        super.viewDidLoad()
        self.drawProgressLayer()
        self.drawGradientLayer()
        self.drawScale()
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    //根据半径画圆
    func drawCurve(Radius r : CGFloat) -> CAShapeLayer {
        let path = UIBezierPath.init(arcCenter: view.center, radius: r, startAngle:-(CGFloat)(M_PI), endAngle:(CGFloat)(M_PI), clockwise: true)
        let curve = CAShapeLayer.init()
        curve.lineWidth = 2.0
        curve.fillColor = UIColor.clear.cgColor
        curve.strokeColor = UIColor.white.cgColor
        curve.path = path.cgPath
        return curve
    }
    
    func drawProgressLayer() {
        let outArc = self.drawCurve(Radius: 147.5)
        let inArc = self.drawCurve(Radius: 82.5)
        view.layer.addSublayer(outArc)
        view.layer.addSublayer(inArc)

        let progressPath = UIBezierPath.init(arcCenter: view.center, radius: 115, startAngle: -(CGFloat)(M_PI), endAngle:0, clockwise: true)
        progressLayer = CAShapeLayer()
        progressLayer?.lineWidth = 60.0
        progressLayer?.fillColor = UIColor.clear.cgColor
        progressLayer?.strokeColor = UIColor.red.cgColor
        progressLayer?.strokeStart = 0
        progressLayer?.strokeEnd = 1
        progressLayer?.path = progressPath.cgPath
        view.layer.addSublayer(progressLayer!)
        
        let progressPath1 = UIBezierPath.init(arcCenter: view.center, radius: 115, startAngle: 0, endAngle:(CGFloat)(M_PI), clockwise: true)
        progressLayer1 = CAShapeLayer()
        progressLayer1?.lineWidth = 60.0
        progressLayer1?.fillColor = UIColor.clear.cgColor
        progressLayer1?.strokeColor = UIColor.red.cgColor
        progressLayer1?.strokeStart = 0
        progressLayer1?.strokeEnd = 1
        progressLayer1?.path = progressPath1.cgPath
        view.layer.addSublayer(progressLayer1!)
    }
    
  func drawGradientLayer() {
        //0~180颜色渐变
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = self.bounds
        gradientLayer.colors = [UIColor.CG_COLOR(颜色数组: [0, 1.00, 1.00,0.5]),UIColor.CG_COLOR(颜色数组: [0, 210/255, 1.00,1.00]),UIColor.CG_COLOR(颜色数组: [38/255, 232/255, 61/255,1.00]),UIColor.CG_COLOR(颜色数组: [38/255, 232/255, 61/255,1.00])]
        gradientLayer.locations = [0,0.25,0.50,0.75,1.0]
        gradientLayer.startPoint = CGPoint.init(x: 0, y: 0)
        gradientLayer.endPoint = CGPoint.init(x: 1, y: 0)
        gradientLayer.mask = progressLayer
        view.layer.addSublayer(gradientLayer)
    
        //180~360颜色渐变
        let gradientLayer1 = CAGradientLayer()
        gradientLayer1.frame = self.bounds
        gradientLayer1.colors = [UIColor.CG_COLOR(颜色数组: [38/255, 232/255, 61/255,1.00]),UIColor.CG_COLOR(颜色数组: [38/255, 232/255, 61/255,1.00]),UIColor.CG_COLOR(颜色数组: [1.00, 153/255, 0,1.00]),UIColor.CG_COLOR(颜色数组: [1.00,0,0,1.00])]
        gradientLayer1.locations = [0,0.25,0.50,0.75,1.0]
        gradientLayer1.startPoint = CGPoint.init(x: 1, y: 0)
        gradientLayer1.endPoint = CGPoint.init(x: 0, y: 0)
        gradientLayer1.mask = progressLayer1
        view.layer.addSublayer(gradientLayer1)

   
    }
    
    //刻度
    func drawScale() {
        let perAngle : CGFloat = CGFloat(M_PI) / 50
        let calWidth : CGFloat = perAngle / 5
        for i in 0...100 {
            let startAngel = CGFloat(-M_PI) + perAngle*CGFloat(i)
            let endAngel = startAngel + calWidth
            let tickPath = UIBezierPath.init(arcCenter: view.center, radius: 140, startAngle: startAngel, endAngle: endAngel, clockwise: true)
            let perLayer = CAShapeLayer()
            if i % 5 == 0 {
                //整数刻度颜色
                perLayer.strokeColor = UIColor.white.cgColor
                perLayer.lineWidth = 10.0
                //整数刻度位置
                let point = self.calculateTextPosition(center: view.center, angle: -startAngel)
                let calibrationLabel = UILabel.init(frame: CGRect.init(x: point.x - 10, y: point.y - 10, width: 30, height: 20))
                if(i == 0){
                  calibrationLabel.text = ""
                }else if(i*2 == 200){
                  calibrationLabel.text = "0/" + String.init(format: "%d", i * 2)
                }else{
                  calibrationLabel.text = String.init(format: "%d", i * 2)
                }
                calibrationLabel.font = UIFont.systemFont(ofSize: 10)
                //整数刻度对应值的颜色
                calibrationLabel.textColor = UIColor.white
                calibrationLabel.textAlignment = .center
                view.addSubview(calibrationLabel)
            }
            else {
                perLayer.strokeColor = UIColor.CG_COLOR(颜色数组: [0.22,0.66,0.87,1.0])
                perLayer.lineWidth = 5
            }
            perLayer.path = tickPath.cgPath
            view.layer.addSublayer(perLayer)
        }
        
        needleLayer = CAShapeLayer()
        needleLayer?.fillColor = UIColor.white.cgColor
        needleLayer?.lineWidth = 1.0
        //指针颜色
        needleLayer?.strokeColor = UIColor.white.cgColor
        view.layer.addSublayer(needleLayer!)
        self.showDataLabel()
        self.drawNeedle(progressValue: 0.0)
    }
    
    //指针
    func drawNeedle(progressValue value:CGFloat) {
       //中心小圆
       // let centerCircle = UIBezierPath.init(arcCenter: view.center, radius: 20, startAngle: CGFloat(-M_PI / 16), endAngle: CGFloat(17 / 16 * M_PI), clockwise: false)
       // let centerCircleLayer = CAShapeLayer()
       // centerCircleLayer.strokeColor = UIColor.red.cgColor
       // centerCircleLayer.lineWidth = 3.0
       // centerCircleLayer.path = centerCircle.cgPath
       // centerCircleLayer.fillColor = UIColor.clear.cgColor
       // view.layer.addSublayer(centerCircleLayer)
        let angel = CGFloat(M_PI) * (1 - value)
        let leewayX : CGFloat = CGFloat(5 * sinf(Float(angel)))
        let leewayY : CGFloat = CGFloat(5 * cosf(Float(angel)))
        let startPX = CGFloat(82.5 * cosf(Float(angel))) + view.center.x
        let startPY = CGFloat(-82.5 * sinf(Float(angel))) + view.center.y
        let startPX1 = startPX - leewayX
        let startPX2 = startPX + leewayX
        let startPY1 = startPY - leewayY
        let startPY2 = startPY + leewayY
        let endPX = CGFloat(110 * cosf(Float(angel))) + view.center.x
        let endPY = CGFloat(-110 * sinf(Float(angel))) + view.center.y
        let needlePath = UIBezierPath.init()
        needlePath.move(to: CGPoint.init(x: startPX1, y: startPY1))
        needlePath.addLine(to: CGPoint.init(x: endPX, y: endPY))
        needlePath.addLine(to: CGPoint.init(x: startPX2, y: startPY2))
        needleLayer?.path = needlePath.cgPath
    }
    
    //计算label位置
    func calculateTextPosition(center:CGPoint,angle:CGFloat) -> CGPoint {
        let calRadius:Float = 125.0
        let x = calRadius * cosf(Float(angle))
        let y = calRadius * sinf(Float(angle))
        return CGPoint.init(x: CGFloat(x) + center.x, y: -CGFloat(y) + center.y)
    }
    
    @IBAction func sliderAction(_ sender: UISlider) {
       // progressLayer?.strokeEnd = CGFloat(sender.value/2)
        self.drawNeedle(progressValue: CGFloat(sender.value))
        self.displayShowLabel(sliderP: CGFloat(sender.value))
    }
    
    //数值显示
    func showDataLabel() {
        
        aLabel = UILabel.init(frame: CGRect.init(x: 0, y: view.center.y-40 , width: self.bounds.size.width, height: 30))
        aLabel?.textColor = UIColor.black
        aLabel?.text = "0"
        aLabel?.font = UIFont.boldSystemFont(ofSize: 30)
        aLabel?.textAlignment = .center
        view.addSubview(aLabel!)
        
        kgLabel = UILabel.init(frame: CGRect.init(x: 0, y: view.center.y , width: self.bounds.size.width, height: 20))
        kgLabel?.textColor = UIColor.black
        kgLabel?.text = "kg"
        kgLabel?.font = UIFont.boldSystemFont(ofSize: 15)
        kgLabel?.textAlignment = .center
        view.addSubview(kgLabel!)
        
        BMILabel = UILabel.init(frame: CGRect.init(x: 0, y: view.center.y+20 , width: self.bounds.size.width, height: 30))
        BMILabel?.textColor = UIColor.black
        BMILabel?.text = "BMI:"+"0"
        BMILabel?.font = UIFont.boldSystemFont(ofSize: 20)
        BMILabel?.textAlignment = .center
        view.addSubview(BMILabel!)
        self.displayShowLabel(sliderP:0.0)
    }
    
    func displayShowLabel(sliderP progress:CGFloat) {
        //format: "%.2f" 保留两位小数
        let numberS : String = String.init(format: "%.1f", progress*100)
        aLabel?.text = numberS
    }
    
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值