[英]IOS custom progress bar with CAShapeLayer
我怎樣才能用弧結束的文字創建一個像這張圖片的自定義弓
這是我當前的代碼和當前結果
let center = view.center
let circularPath = UIBezierPath(arcCenter: center, radius: 120, startAngle: CGFloat.pi , endAngle: CGFloat.pi*2, clockwise: true)
let greyLayer = CAShapeLayer()
greyLayer.strokeColor = greyColor
greyLayer.lineWidth = lineWidth
greyLayer.path = circularPath.cgPath
greyLayer.lineCap = .round
greyLayer.fillColor = UIColor.clear.cgColor
greyLayer.shadowColor = UIColor.black.cgColor
greyLayer.shadowOpacity = 1
greyLayer.shadowOffset = .zero
greyLayer.shadowRadius = 2
view.layer.addSublayer(greyLayer)
shapeLayer.strokeColor = bowColor
shapeLayer.lineWidth = lineWidth
shapeLayer.path = circularPath.cgPath
shapeLayer.lineCap = .round
shapeLayer.strokeEnd = 0
shapeLayer.fillColor = UIColor.clear.cgColor
view.layer.addSublayer(shapeLayer)
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
let label = UILabel()
label.text = "Best"
label.textAlignment = .center
label.textColor = .red
label.font = UIFont.boldSystemFont(ofSize: 30)
view.addSubview(label)
view.layer.addSublayer(label.layer)
label.translatesAutoresizingMaskIntoConstraints = false
label.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
label.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
label.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
label.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
當前結果我想在圓弧的末端添加一個圓形並像上圖一樣動畫,我不知道如何實現這個
為了讓你開始...
您的弧線從.pi
變為.pi*2
...但不是.pi*2
它可能會幫助您將其視為:
.pi
開始,即“9 點鍾”.pi
到起始角度完成進度為.pi
加上.pi * progressPercent
。
因此,要獲得endAngle
:
.pi + ((25.0 / 100.0) *.pi)
.pi + ((50.0 / 100.0) *.pi)
.pi + ((83.0 / 100.0) *.pi)
編碼,你會做這樣的事情:
let score = 83
let endAngle: CGFloat = .pi + ((CGFloat(score) / 100.0) * .pi)
let center = view.center
let circularPath = UIBezierPath(arcCenter: center, radius: 120, startAngle: .pi, endAngle: endAngle, clockwise: true)
現在你的弧線跨越了 83% 的“半圓”。
要在弧的末端添加 label,您可以從路徑中獲取該點:
// point at end of arc
let endPoint: CGPoint = circularPath.currentPoint
您可以使用該點指向 position 您的 label(或自定義“氣球”label 視圖)。
這是您的代碼,稍作修改以添加一個score
值和一個progressLabel
:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemTeal
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let greyColor = UIColor.gray.cgColor
let bowColor = UIColor.systemPink.cgColor
let lineWidth: CGFloat = 12
let shapeLayer = CAShapeLayer()
let score = 83
let endAngle: CGFloat = .pi + (.pi * (CGFloat(score) / 100.0))
let center = view.center
let circularPath = UIBezierPath(arcCenter: center, radius: 120, startAngle: .pi, endAngle: endAngle, clockwise: true)
// point at end of arc
let endPoint: CGPoint = circularPath.currentPoint
let greyLayer = CAShapeLayer()
greyLayer.strokeColor = greyColor
greyLayer.lineWidth = lineWidth
greyLayer.path = circularPath.cgPath
greyLayer.lineCap = .round
greyLayer.fillColor = UIColor.clear.cgColor
greyLayer.shadowColor = UIColor.black.cgColor
greyLayer.shadowOpacity = 1
greyLayer.shadowOffset = .zero
greyLayer.shadowRadius = 2
view.layer.addSublayer(greyLayer)
shapeLayer.strokeColor = bowColor
shapeLayer.lineWidth = lineWidth
shapeLayer.path = circularPath.cgPath
shapeLayer.lineCap = .round
shapeLayer.strokeEnd = 0
shapeLayer.fillColor = UIColor.clear.cgColor
view.layer.addSublayer(shapeLayer)
//view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
let label = UILabel()
label.text = "Best"
label.textAlignment = .center
label.textColor = .red
label.font = UIFont.boldSystemFont(ofSize: 30)
view.addSubview(label)
view.layer.addSublayer(label.layer)
label.translatesAutoresizingMaskIntoConstraints = false
label.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
label.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
label.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
label.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
let progressLabel = UILabel()
progressLabel.backgroundColor = .cyan
progressLabel.text = "\(score)%"
progressLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(progressLabel)
progressLabel.bottomAnchor.constraint(equalTo: view.topAnchor, constant: endPoint.y).isActive = true
progressLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: endPoint.x).isActive = true
}
}
結果:
如果您想“動畫化”進度弧和 label,那將需要更多的工作......但這是一個很好的學習練習讓您承擔。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.