import UIKit
class SPCircleAnimationView: UIView {
private var progress: CGFloat = 0
private var circleColor: UIColor = .orange
private var bottomLine = CAShapeLayer()
private var circleLine = CAShapeLayer()
private var pathAnimation = CABasicAnimation()
private var opacityAnimation = CABasicAnimation()
init(frame: CGRect, progress: CGFloat, color: UIColor = .orange) {
super.init(frame: CGRect(x: frame.origin.x, y: frame.origin.y, width: frame.width, height: frame.width))
backgroundColor = .clear
clipsToBounds = true
self.progress = progress
self.circleColor = color
setupAnimation()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupAnimation() {
circleLine.lineCap = .round
circleLine.lineJoin = .round
circleLine.fillColor = UIColor.clear.cgColor
circleLine.lineWidth = 6
circleLine.strokeEnd = 0
bottomLine.fillColor = UIColor.clear.cgColor
bottomLine.lineWidth = 6
bottomLine.opacity = 0
layer.addSublayer(bottomLine)
layer.addSublayer(circleLine)
}
override func draw(_ rect: CGRect) {
let bottom = UIBezierPath(arcCenter: CGPoint(x: bounds.width * 0.5, y: bounds.height * 0.5), radius: bounds.width * 0.5 - 3, startAngle: -.pi / 2.0, endAngle: .pi * 3.0 / 2.0, clockwise: true)
bottomLine.path = bottom.cgPath
bottomLine.strokeColor = circleColor.cgColor
opacityAnimation.keyPath = "opacity"
opacityAnimation.fromValue = 0
opacityAnimation.toValue = 0.3
opacityAnimation.duration = 1
opacityAnimation.fillMode = .forwards
opacityAnimation.isRemovedOnCompletion = false
let circle = UIBezierPath(arcCenter: CGPoint(x: bounds.width * 0.5, y: bounds.height * 0.5), radius: bounds.width * 0.5 - 3, startAngle: -.pi / 2.0, endAngle: .pi * 3.0 / 2.0, clockwise: true)
circleLine.path = circle.cgPath
circleLine.strokeColor = circleColor.cgColor
pathAnimation.keyPath = "strokeEnd"
pathAnimation.fromValue = 0
pathAnimation.toValue = progress
pathAnimation.duration = 1
}
func drawChartLine() {
circleLine.strokeEnd = CGFloat(progress)
circleLine.add(pathAnimation, forKey: nil)
bottomLine.add(opacityAnimation, forKey: nil)
}
}
![](https://img.haomeiwen.com/i7424468/24b8e555f8a3dc8f.png)
image.png
class SPProgressView: UIView {
var progress: CGFloat = 0 {
willSet {
DispatchQueue.main.async {
self.setNeedsDisplay()
}
}
}
var lineWidth: CGFloat = 6
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .clear
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
let bottomPath = UIBezierPath(arcCenter: CGPoint(x: bounds.width * 0.5, y: bounds.height * 0.5), radius: (bounds.width - lineWidth) * 0.5, startAngle: 0, endAngle: .pi * 2, clockwise: true)
bottomPath.lineWidth = lineWidth
UIColor.init(white: 0, alpha: 0.2).setStroke()
UIColor.clear.setFill()
bottomPath.stroke()
bottomPath.fill()
let path = UIBezierPath(arcCenter: CGPoint(x: bounds.width * 0.5, y: bounds.height * 0.5), radius: (bounds.width - lineWidth) * 0.5, startAngle: .pi * 3 / 2, endAngle: .pi * 2 * progress - .pi / 2, clockwise: true)
path.lineWidth = lineWidth
UIColor.orange.setStroke()
path.stroke()
}
}
![](https://img.haomeiwen.com/i7424468/6308a6630287a46a.jpg)
image.jpg
网友评论