跟大家分享一个雷达扫描得小东西,
制作这个效果分为以下几步:
1:首先画出范围
详见主要代码:
let context = UIGraphicsGetCurrentContext()
context?.move(to: CGPoint.init(x: 0, y: self.bounds.size.height*0.5))
context?.setStrokeColor(red: 8.0/255.0, green: 242.0/255.0, blue: 46.0/255.0, alpha: 1)
context?.setLineWidth(1)
context?.addLine(to: CGPoint.init(x: self.bounds.size.width, y: self.bounds.size.height*0.5))
context?.move(to: CGPoint.init(x: self.bounds.size.width*0.5, y: (self.bounds.size.height - self.bounds.size.width)*0.5))
context?.addLine(to: CGPoint.init(x: self.bounds.size.width*0.5, y:self.bounds.size.height - (self.bounds.size.height - self.bounds.size.width)*0.5))
context?.closePath()
context?.drawPath(using: .stroke)
var sectionRadius = radius / CGFloat(sectionsNum)//这个是几个圈
for i in 0..<sectionsNum{
context?.setLineWidth(1)
context?.addArc(center: CGPoint.init(x: self.center.x, y: self.center.y), radius: CGFloat(sectionRadius - CGFloat(5*(sectionsNum - i - 1))), startAngle: 0, endAngle: CGFloat(2*M_PI), clockwise:false)
context?.drawPath(using: .stroke)
sectionRadius += radius / CGFloat(sectionsNum)
}
2:对于点的处理(主要是点在视图位置的处理,对于点这个类加一些动画操作,这里就不过多的说了),具体见主要代码详情
_ = self.pointsView?.subviews.map({ $0.removeFromSuperview() })
let pointsNum = self.dataSource?.numberOfPointsInRadarView(radarView: self)
for index in 0..<Int(pointsNum!) {
let point:CGPoint = (self.dataSource?.radarView(radarView: self, positionForIndex: index))!
let posDirection = point.x
let posDistance = point.y
let pointView = WJFRadrarPointView.init(frame: CGRect.zero)
let customView = self.dataSource?.radarView(radarView: self, viewForIndex: index)
pointView.addSubview(customView!)
pointView.tag = index
pointView.frame = (customView?.frame)!
pointView.center = CGPoint.init(x: self.center.x+posDistance*sin(posDirection * CGFloat( M_PI / 180)), y: self.center.y + posDistance * cos(posDirection * CGFloat(M_PI / 180)))
pointView.delegate = self
pointView.alpha = 1.0
let fromTransform = pointsView?.transform.scaledBy(x: 0.1, y: 0.2)
pointView.transform = fromTransform!
let toTransform = pointView.transform.concatenating((pointView.transform.inverted()))
let delayInSeconds = 0.1 * Double(index)
// DispatchQueue.aft
self.pointsView?.addSubview(pointView)
pointView.transform = toTransform
}
3:就是前面GIF展示的,对于扫描区的处理
3.1创建扫描区,主要就是 创建一个三角弧区域
override func draw(_ rect: CGRect) {
super.draw(rect)
//画布
let context = UIGraphicsGetCurrentContext()
let startColor = self.startColor
context?.setFillColor((startColor?.cgColor)!)//填充颜色
context?.setLineWidth(0)
context?.move(to: CGPoint.init(x: self.center.x, y: self.center.y))
context?.addArc(center: CGPoint.init(x: self.center.x, y: self.center.y) , radius: self.radius!, startAngle: ((self.clockwise! ? self.anglee! : 0) * CGFloat(M_PI / 180)), endAngle: (self.clockwise! ? (self.anglee! - 1) : 1) * CGFloat(M_PI / 180), clockwise: self.clockwise!)
context?.closePath()
context?.drawPath(using: .fillStroke)
let startColorComponents = (self.startColor?.cgColor)?.components
let endColorComponents = (self.endColor?.cgColor)?.components
var R:CGFloat = 0.0
var G:CGFloat = 0.0
var B:CGFloat = 0.0
var A:CGFloat = 0.0
for index in 0...Int(self.anglee!) {
let ratio = (self.clockwise! ? (self.anglee! - CGFloat(index)) : CGFloat(index)) / self.anglee!
R = (startColorComponents?[0])! - ((startColorComponents?[0])! - (endColorComponents?[0])!) * ratio
G = (startColorComponents?[1])! - ((startColorComponents?[1])! - (endColorComponents?[1])!) * ratio
B = (startColorComponents?[2])! - ((startColorComponents?[2])! - (endColorComponents?[2])!) * ratio
A = (startColorComponents?[3])! - ((startColorComponents?[3])! - (endColorComponents?[3])!) * ratio
let startColor = UIColor.init(red: R, green: G, blue: B, alpha: A)
context?.setFillColor(startColor.cgColor)
context?.setLineWidth(0)
context?.move(to: CGPoint.init(x: self.center.x, y: self.center.y))
context?.addArc(center: CGPoint.init(x: self.center.x, y: self.center.y) , radius: self.radius!, startAngle: CGFloat(Double(index) * M_PI / 180), endAngle: CGFloat((Double(index) + (self.clockwise! ? -1 : 1)) * M_PI / 180), clockwise: self.clockwise!)
context?.closePath()
context?.drawPath(using: .fillStroke)
}}
3.2 让这个区域动起来,比较简单的一个核心动画
let rotationAnimation = CABasicAnimation.init(keyPath: "transform.rotation.z")
var indicatorClockwise = true
if self.indicatorClockwise != nil {
indicatorClockwise = self.indicatorClockwise!
}
rotationAnimation.toValue = (indicatorClockwise ? 1 : -1) * M_PI * 2.0
rotationAnimation.duration = 360.0 / 60
rotationAnimation.isCumulative = true
rotationAnimation.repeatCount = Float(INT_MAX)
self.indicatorView?.layer.add(rotationAnimation, forKey: "rotationAnimation")
至此,swift版的雷达简单版就出来了