// // SBTDashboardView.swift // SolarBT // // Created by weclouds on 2019/3/29. // Copyright © 2019 weclouds. All rights reserved. // import UIKit class SBTDashboardView: UIView { var circle000: CAShapeLayer! //刻度数目 var scaleNumber : Int? //开始弧度 var start : CGFloat? //结束弧度 var end : CGFloat? var pointView:UIView?// 指针 var angle:CGFloat? var perAngle:CGFloat? var backAnge:CGFloat? var space: CGFloat? var radius1 :CGFloat? var radius2 :CGFloat? var radius3 :CGFloat? var radius4 :CGFloat? var number : Int? var powerValue : CGFloat?{ didSet{ if let powerValue = self.powerValue { circle000.strokeEnd = powerValue let ang = angle! * powerValue - angle! / 2 UIView.animate(withDuration: 0) { self.circle000.strokeEnd = powerValue let value = powerValue * 84 // if value.isNaN == false{// 空值 self.update(Int(value)) // }else{ // self.update(0) // } self.pointView?.transform = CGAffineTransform(rotationAngle: ang ) // self.pointView?.transform = CGAffineTransform.identity. } backAnge = ang } } } var solarPowerValue: String?{ didSet{ let str = solarPowerValue! + "W" let attrStr = NSMutableAttributedString(string: str) attrStr.addAttributes([NSAttributedString.Key.font:UIFont(name: PingFangSC_Semibold, size: 22) as Any], range: NSRange(location: 0, length: str.count - 1)) attrStr.addAttributes([NSAttributedString.Key.font:UIFont(name: PingFangSC_Semibold, size: 9) as Any], range: NSRange(location: str.count - 1, length: 1)) valueLabel.attributedText = attrStr } } var scaleLayer : [CAShapeLayer]? lazy var valueLabel: UILabel = { let valueLabel = UILabel() valueLabel.textAlignment = .center valueLabel.textColor = UIColor(hexString: "3B3B3B") return valueLabel }() lazy var powerLabel1: UILabel = { let powerLabel1 = UILabel() powerLabel1.text = "Solar_panel_power".da_localizedStr() powerLabel1.textAlignment = .center powerLabel1.font = UIFont(name: PingFangSC_Medium, size: 8) powerLabel1.textColor = UIColor(hexString: "A5A5A5") return powerLabel1 }() lazy var statusView : UIImageView = { let statusView = UIImageView(image: UIImage(named: "power_status")) return statusView }() lazy var statusLabel: UILabel = { let label = UILabel() label.font = UIFont(name: PingFangSC_Medium, size: 8) label.textColor = UIColor(hexString: "#A5A5A5") label.text = "Normal".da_localizedStr() return label }() override init(frame: CGRect) { super.init(frame: frame) // self.backgroundColor = UIColor.cyan space = 30 radius1 = (self.frame.size.width - space! * 2 ) / 2 - 5 radius2 = radius1! - 10 radius3 = radius2! - radius1! / 2 radius4 = 5 number = 84 start = .pi * 2 / 3 end = .pi / 3 //计算总弧度 angle = 2 * .pi * 5 / 6 perAngle = angle! / (CGFloat(number!) - 1) scaleLayer = [CAShapeLayer]() createUI() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func update(_ value: Int) { for layer in scaleLayer! { layer.removeFromSuperlayer() } drawScale(number: value) } func createUI() { // addSubview(statusView) // statusView.addSubview(statusLabel) drawCircle() drawCircle2() drawCircle3() drawPointer() renderCircle() addSubview(valueLabel) addSubview(powerLabel1) valueLabel.snp.makeConstraints { (make) in make.centerX.equalToSuperview() make.top.equalToSuperview().offset(75) make.height.equalTo(22) } powerLabel1.snp.makeConstraints { (make) in make.centerX.equalToSuperview() make.top.equalTo(valueLabel.snp.bottom).offset(0) make.height.equalTo(11) } // statusView.snp.makeConstraints { (make) in // make.centerX.equalToSuperview() // make.top.equalTo(powerLabel1.snp.bottom).offset(8) // make.width.equalTo(60) // make.height.equalTo(30) // } // // statusLabel.snp.makeConstraints { (make) in // make.centerX.equalToSuperview() // make.bottom.equalToSuperview().offset(-5) // } } func drawPointer() { pointView = UIView(frame: CGRect(x: self.center.x - radius4! / 4, y: self.centerY - radius1! , width: radius4! / 2, height: radius1! )) pointView?.backgroundColor = UIColor(hexString: "#FD8C23") addSubview(pointView!) let path1 = UIBezierPath() path1 .move(to: CGPoint(x: 0, y: 0)) path1.addLine(to: CGPoint(x: (pointView?.frame.size.width)!, y: 0)) path1.addLine(to: CGPoint(x: (pointView?.frame.size.width)! / 2, y: (pointView?.frame.size.height)! - 30 )) path1.close() let layer1 = CAShapeLayer() layer1.frame = pointView!.bounds layer1.path = path1.cgPath layer1.lineJoin = .round layer1.lineCap = .round pointView?.layer.mask = layer1 let oldFrame = pointView?.frame pointView?.layer.anchorPoint = CGPoint(x: 0.5, y: 1) pointView?.frame = oldFrame! pointView?.transform = CGAffineTransform(rotationAngle: -angle! / 2) } //绘制外围圆环 func drawCircle() { let layer2 = CAShapeLayer() layer2.lineWidth = 30 layer2.frame = self.bounds // 圆环的颜色 layer2.strokeColor = UIColor(hexString: "#F8F8F8")?.cgColor layer2.fillColor = UIColor.clear.cgColor //设置半径为视图的半径 let radius : CGFloat = 188 / 2 - 13 //初始化一个路径 let path2 = UIBezierPath(arcCenter: self.center, radius: radius, startAngle: 0, endAngle: 2 * .pi, clockwise: true) // 是否是逆时针 layer2.path = path2.cgPath self.layer.addSublayer(layer2) } //绘制外围圆环 func drawCircle2() { let layer3 = CAShapeLayer() layer3.lineWidth = 1 layer3.frame = self.bounds // 圆环的颜色 layer3.strokeColor = UIColor(hexString: "#D8D8D8")?.cgColor layer3.fillColor = UIColor.clear.cgColor //设置半径为视图的半径 let radius : CGFloat = 188 / 2 //初始化一个路径 let path3 = UIBezierPath(arcCenter: self.center, radius: radius, startAngle: 0, endAngle: 2 * .pi, clockwise: true) // 是否是逆时针 layer3.path = path3.cgPath self.layer.addSublayer(layer3) } //绘制外围圆环 func drawCircle3() { let layer4 = CAShapeLayer() layer4.lineWidth = 1 layer4.frame = self.bounds // 圆环的颜色 layer4.strokeColor = UIColor(hexString: "#D8D8D8")?.cgColor layer4.fillColor = UIColor.clear.cgColor //设置半径为视图的半径 let radius : CGFloat = 188 / 2 - 26 //初始化一个路径 let path4 = UIBezierPath(arcCenter: self.center, radius: radius, startAngle: 0, endAngle: 2 * .pi, clockwise: true) // 是否是逆时针 layer4.path = path4.cgPath self.layer.addSublayer(layer4) } //进度圆环 func renderCircle() { let startAngle: CGFloat = start! let endAngle: CGFloat = end! let centerX = 188 / 2 let centerY = 188 / 2 let center = CGPoint(x: centerX,y: centerY) let lineWidth: CGFloat = 3.0 let radius = 188 / 2 - 26 circle000 = CAShapeLayer() //绘制圆 let circlePath = UIBezierPath.init(arcCenter: center, radius: CGFloat(radius), startAngle: startAngle, endAngle: endAngle, clockwise: true) circle000.path = circlePath.cgPath //中间透明 circle000.fillColor = UIColor.clear.cgColor //临时颜色,下面会用到渐变色来渲染圆环颜色 circle000.strokeColor = UIColor.green.cgColor //设置线宽 circle000.lineWidth = lineWidth //设置圆环头部样式 circle000.lineCap = CAShapeLayerLineCap.round //把自己定义的circle 添加到 背景圆环的layer上 self.layer.addSublayer(circle000) //下面重点来了: //1. 之所以能实现圆环的渐变色,并不是我们可以直接在layer上添加一个圆环形状的渐变色,而是 //创建一个通用的正方形渐变色区域,用我们的circle 作为这个渐变区域的mask来截取一个圆环形状的渐变色 //区域。 //2. 为了制造圆环的渐变色效果,只创建一块渐变区域,那是不够的,因为那样画出来的圆左右方向的圆弧颜色 //是对称的,那样就太丑了,不符合整体渐变的要求。所以,我把这个正方形渐变区域垂直切分成两块渐变区域, //左右区域的颜色顺序相反,起始和结束位置也相反,就出来圆环渐变的效果了。 let gradientLayer = CALayer() //创建第一个gradientLayer let colors1 = [ UIColor.RGBA(red: 255, green: 122, blue: 0, alpha: 1.0).cgColor, UIColor.RGBA(red: 248, green: 248, blue: 248, alpha: 1.0).cgColor // UIColor.RGBA(red: 255, green: 122, blue: 0, alpha: 1.0).cgColor ] let frame1 = CGRect(x: 0, y: 0, width: self.width, height: self.height ) let gradientLayer1 = CAGradientLayer() gradientLayer1.startPoint = CGPoint(x: 0.5,y: 0) gradientLayer1.endPoint = CGPoint(x: 0.5,y: 1) gradientLayer1.frame = frame1 gradientLayer1.colors = colors1 //用一个gradientLayer来承接这两个渐变区域 gradientLayer.addSublayer(gradientLayer1) //用circle的path形状来截取渐变区域 gradientLayer.mask = circle000 self.layer.addSublayer(gradientLayer) } //绘制刻度盘 func drawScale(number scaleN: Int ) { let color = UIColor(hexString: "#FF7A00") let color2 = UIColor(hexString: "#D8D8D8") // let scaleA = scaleN / 100 * number! // let color = UIColor.red // let color2 = UIColor.yellow log.debug("刻度数 - \(scaleN)") for i in 0.. UIColor{ return UIColor(red: red/255, green: green/255, blue: blue/255, alpha: alpha) } }