Равномерно распределенные цвета на CAGradientLayer - PullRequest
0 голосов
/ 12 апреля 2019

Эй, у меня есть круг с градиентным прогрессом, вот так:

enter image description here

Код следующий:

@IBDesignable class DashboardMetricCircleView: UIView {

    enum Constants {
        static let duration: Double = 1.5
        static let lineWidth: CGFloat = 4.0
    }

    let circleBgLayer: CAShapeLayer = CAShapeLayer()
    let circleProgressLayer: CAShapeLayer = CAShapeLayer()
    let gradientLayer: CAGradientLayer = CAGradientLayer()

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    private func setup() {
        layer.addSublayer(circleBgLayer)
        layer.addSublayer(gradientLayer)

        circleBgLayer.shouldRasterize = true
        circleBgLayer.rasterizationScale = UIScreen.main.scale * 2.0
        circleBgLayer.strokeColor = Theme.background.cgColor
        circleBgLayer.fillColor = nil
        circleBgLayer.lineWidth = Constants.lineWidth

        circleProgressLayer.shouldRasterize = true
        circleProgressLayer.rasterizationScale = UIScreen.main.scale * 2.0
        circleProgressLayer.strokeColor = UIColor.black.cgColor
        circleProgressLayer.lineCap = .round
        circleProgressLayer.fillColor = nil
        circleProgressLayer.lineWidth = Constants.lineWidth
        circleProgressLayer.strokeStart = 0.0
        circleProgressLayer.strokeEnd = 0.0

        gradientLayer.mask = circleProgressLayer
        gradientLayer.shouldRasterize = true
        gradientLayer.rasterizationScale = UIScreen.main.scale * 2.0
        gradientLayer.colors = [
            UIColor.red.cgColor,
            UIColor.yellow.cgColor
        ]
    }

    func animate(progress: CGFloat) {
        let animateStroke = CABasicAnimation(keyPath: "strokeEnd")
        animateStroke.toValue = progress
        animateStroke.duration = Constants.duration
        animateStroke.isRemovedOnCompletion = false
        animateStroke.fillMode = .forwards
        circleProgressLayer.add(animateStroke, forKey: "MyAnimation")
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        circleBgLayer.frame = bounds
        circleProgressLayer.frame = bounds
        gradientLayer.frame = bounds

        let centerPt = CGPoint(x: bounds.width / 2.0, y: bounds.width / 2.0)
        let radius = bounds.width / 2.0 - Constants.lineWidth / 2.0
        circleBgLayer.path = UIBezierPath(arcCenter: centerPt, radius: radius, startAngle: 0.0, endAngle: CGFloat.pi * 2.0, clockwise: true).cgPath
        circleProgressLayer.path = UIBezierPath(arcCenter: centerPt, radius: radius, startAngle: CGFloat.pi * 3/2, endAngle: CGFloat.pi * 7/2, clockwise: true).cgPath
    }

}

Я хочу сделать градиент равномерно распределенным. Желтый должен начинаться в 12 часов и постепенно превращаться в красный, когда доходит до конца одного оборота. Как я могу настроить градиент, чтобы сделать это?

...