代码之家  ›  专栏  ›  技术社区  ›  Wazza

更改“油炸圈饼”视图周围的颜色渐变

  •  1
  • Wazza  · 技术社区  · 7 年前

    我正在尝试制作一个动画甜甜圈视图,当给定一个介于0和100之间的值时,它将动画化视图,直到达到这个数字。我有这个工作很好,但想褪色的颜色从一个到另一个,然后另一个在路上。目前,当我添加渐变时,它会从左向右移动,而不是沿着甜甜圈视图的圆周。

        class CircleScoreView: UIView {
            private let outerCircleLayer = CAShapeLayer()
            private let outerCircleGradientLayer = CAGradientLayer()
            private let outerCircleLineWidth: CGFloat = 5
    
            override init(frame: CGRect) {
                super.init(frame: .zero)
            }
    
            required init?(coder aDecoder: NSCoder) {
                fatalError("init(coder:) has not been implemented")
            }
    
            override func layoutSubviews() {
                super.layoutSubviews()
                buildLayers()
            }
    
            /// Value must be within 0...100 range
            func setScore(_ value: Int, animated: Bool = false) {
                if value != 0 {
                    let clampedValue: CGFloat = CGFloat(value.clamped(to: 0...100)) / 100
                    if !animated {
                        outerCircleLayer.strokeEnd = clampedValue
                    } else {
                        let outerCircleAnimation = CABasicAnimation(keyPath: "strokeEnd")
                        outerCircleAnimation.duration = 1.0
                        outerCircleAnimation.fromValue = 0
                        outerCircleAnimation.toValue = clampedValue
                        outerCircleAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
    
                        outerCircleLayer.strokeEnd = clampedValue
                        outerCircleLayer.add(outerCircleAnimation, forKey: "outerCircleAnimation")
                    }
    
                    outerCircleGradientLayer.colors = [Constant.Palette.CircleScoreView.startValue.cgColor,
                                                       Constant.Palette.CircleScoreView.middleValue.cgColor,
                                                       Constant.Palette.CircleScoreView.endValue.cgColor]
                }
            }
    
            private func buildLayers() {
    
                // Outer background circle
                let arcCenter = CGPoint(x: frame.size.width / 2, y: frame.size.height / 2)
                let startAngle = CGFloat(-0.5 * Double.pi)
                let endAngle =  CGFloat(1.5 * Double.pi)
    
                let circlePath = UIBezierPath(arcCenter: arcCenter,
                                              radius: (frame.size.width - outerCircleLineWidth) / 2,
                                              startAngle: startAngle,
                                              endAngle: endAngle,
                                              clockwise: true)
    
                // Outer circle
                setupOuterCircle(outerCirclePath: circlePath)
            }
    
            private func setupOuterCircle(outerCirclePath: UIBezierPath) {
                outerCircleLayer.path = outerCirclePath.cgPath
                outerCircleLayer.fillColor = UIColor.clear.cgColor
                outerCircleLayer.strokeColor = UIColor.black.cgColor
                outerCircleLayer.lineWidth = outerCircleLineWidth
                outerCircleLayer.lineCap = CAShapeLayerLineCap.round
    
                outerCircleGradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
                outerCircleGradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
                outerCircleGradientLayer.frame = bounds
                outerCircleGradientLayer.mask = outerCircleLayer
                layer.addSublayer(outerCircleGradientLayer)
            }
        }
    

    我想要的是 this 但是颜色不是一个块,而是甜甜圈视图周围从一种颜色到下一种颜色的渐变。

    1 回复  |  直到 7 年前
        1
  •  0
  •   hirsch    7 年前

    如果你进口 AngleGradientLayer 在你的项目中,你需要做的就是改变:
    private let outerCircleGradientLayer = CAGradientLayer()
    private let outerCircleGradientLayer = AngleGradientLayer()