将颜色渐变添加到圆形进度条iOS

时间:2020-05-10 08:07:50

标签: ios swift xcode calayer cashapelayer

我在向圆形进度栏添加颜色渐变时遇到困难

enter image description here

我的设置:

  1. 故事板:ViewController,其中有一个空视图,指定为Class CircularProgressBar
  2. CircularProgressBar的自定义类

已采取的步骤:

  1. 我能够加载循环进度条
  2. 在较早的尝试中,我创建了一个渐变形状图层并将其设置为被BarLayer的边界遮盖,但是渐变形状图层从我的圆心开始绘制一个矩形,并延伸到右下角,因此仅该部分的BarLayer会有一个梯度
  3. 当我移动渐变层矩形的原点时,它会将Barlayer移离了TrackLayer。

我如何:

让渐变层覆盖整个圆形进度条并将其遮罩到BarLayer

class CircularProgressBar: UIView {

let shapeLayer = CAShapeLayer()
let trackLayer = CAShapeLayer()

override init(frame: CGRect) {
super.init(frame: frame)
    addProgressBar(radius: 5, progress: 0)
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
    addProgressBar(radius: 5, progress: 0)
}

func addProgressBar(radius: CGFloat, progress: CGFloat) {

    let lineWidth = radius*0.080

    let circularPath = UIBezierPath(arcCenter: CGPoint(x: bounds.midX, y: bounds.midY), radius: radius, startAngle: 0, endAngle: CGFloat.pi*2, clockwise: true)

    //TrackLayer
    trackLayer.path = circularPath.cgPath
    trackLayer.fillColor = UIColor.lightGray.cgColor
    trackLayer.strokeColor = UIColor.clear.cgColor
    trackLayer.opacity = 0.5
    trackLayer.lineWidth = lineWidth
    trackLayer.lineCap = CAShapeLayerLineCap.round

    //BarLayer
    shapeLayer.path = circularPath.cgPath
    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.strokeColor = UIColor.systemGreen.cgColor
    shapeLayer.lineWidth = lineWidth
    shapeLayer.strokeEnd = 0
    shapeLayer.lineCap = CAShapeLayerLineCap.round



    //Rotate Shape Layer
    shapeLayer.transform = CATransform3DMakeRotation(-CGFloat.pi/2, 0, 0, 1)

//Shape Shadow
    shapeLayer.shadowColor = UIColor.black.cgColor
    shapeLayer.shadowOffset = CGSize(width: -7, height: 7)
    shapeLayer.shadowRadius = 1
    shapeLayer.shadowOpacity = 0.5

    //Animation
    loadProgress(percentage: progress)

    //LoadLayers
    layer.addSublayer(trackLayer)
    layer.addSublayer(shapeLayer)

}  
func loadProgress(percentage: CGFloat) {

    let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")
    basicAnimation.fromValue = 0
    basicAnimation.duration = 2
    basicAnimation.fillMode = CAMediaTimingFillMode.forwards
    basicAnimation.isRemovedOnCompletion = false
    shapeLayer.strokeEnd = percentage
    shapeLayer.add(basicAnimation, forKey: "basicStroke")

}

ViewController

class HomeViewController: UIViewController {

@IBOutlet weak var containerView: UIView!


var circularProgressBar = CircularProgressBar()
var radius: CGFloat!
var progress: CGFloat!

var answeredCorrect = 0
var totalQuestions = 0


override func viewDidLoad() {
    super.viewDidLoad()

    answeredCorrect = 50
    totalQuestions = 100

    //Configure Progress Bar
    radius = (containerView.frame.height)/2.60
    progress = CGFloat(answeredCorrect) / CGFloat (totalQuestions)
    circularProgressBar.addProgressBar(radius: radius, progress: progress)
    circularProgressBar.center = containerView.center

    //Adding view
    containerView.addSubview(circularProgressBar)


}  
}

1 个答案:

答案 0 :(得分:1)

如果您正在寻找类似的东西

enter image description here

您需要更新代码

import UIKit
@IBDesignable
class CircularProgressBar: UIView {

let shapeLayer = CAShapeLayer()
let trackLayer = CAShapeLayer()

override init(frame: CGRect) {
super.init(frame: frame)
   // addProgressBar(radius: 50, progress: 50)
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
   // addProgressBar(radius: 50, progress: 50)
}
  override func layoutSubviews() {
    addProgressBar(radius: 50, progress: 50)
  }
func addProgressBar(radius: CGFloat, progress: CGFloat) {

  let lineWidth = CGFloat(10.0)//radius*0.080

    let circularPath = UIBezierPath(arcCenter: CGPoint(x: bounds.midX, y: bounds.midY), radius: radius, startAngle: 0, endAngle: CGFloat.pi*2, clockwise: true)

    //TrackLayer
    trackLayer.path = circularPath.cgPath
    trackLayer.fillColor = UIColor.lightGray.cgColor
    trackLayer.strokeColor = UIColor.clear.cgColor
    trackLayer.lineWidth = lineWidth
    trackLayer.lineCap = CAShapeLayerLineCap.round

    //BarLayer
    shapeLayer.path = circularPath.cgPath
    shapeLayer.fillColor = UIColor.black.cgColor
    shapeLayer.strokeColor = UIColor.systemGreen.cgColor
    shapeLayer.lineWidth = lineWidth*2
    //shapeLayer.strokeEnd = 0
    shapeLayer.lineCap = CAShapeLayerLineCap.round

    //Rotate Shape Layer
   // shapeLayer.transform = CATransform3DMakeRotation(-CGFloat.pi/2, 0, 0, 1)

    //Animation
   // loadProgress(percentage: progress)

    //LoadLayers
   layer.addSublayer(trackLayer)
   self.addGradient()

  // layer.addSublayer(shapeLayer)

}

  private func addGradient() {
    let gradient = CAGradientLayer()
    gradient.colors = [UIColor.red.cgColor,UIColor.purple.cgColor,UIColor.systemPink.cgColor,UIColor.blue.cgColor]
    gradient.frame = bounds
    gradient.mask = shapeLayer
    layer.addSublayer(gradient)
  }
}

对于均匀渐变,您可以替换addGradient方法

enter image description here

private func addGradient() {
    let gradient = CAGradientLayer()
    gradient.colors = [UIColor.red.cgColor,UIColor.cyan.cgColor,UIColor.brown.cgColor,UIColor.blue.cgColor]
    gradient.frame = bounds
    gradient.locations = [0.2,0.5,0.75,1]
    gradient.startPoint = CGPoint(x: 0.5, y: 0.5)
    gradient.endPoint = CGPoint(x: 0.5, y: 0)
    gradient.type = .conic
    gradient.mask = shapeLayer
    layer.addSublayer(gradient)
  }