【问题标题】:Apply gradient color to arc created with UIBezierPath将渐变颜色应用于使用 UIBezierPath 创建的弧线
【发布时间】:2014-01-05 00:12:18
【问题描述】:

我想创建一个弧形的进度条。进度条的颜色必须根据值更改。

我使用UIBezierPath bezierPathWithArcCenter 创建了一个弧。我使用了以下代码:

- (void)viewDidLoad
{
    [super viewDidLoad];

    int radius = 100;

    CAShapeLayer *arc = [CAShapeLayer layer];

    arc.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 50) radius:radius startAngle:60.0 endAngle:0.0 clockwise:YES].CGPath;

    arc.position = CGPointMake(CGRectGetMidX(self.view.frame)-radius,
                                  CGRectGetMidY(self.view.frame)-radius);

    arc.fillColor = [UIColor clearColor].CGColor;
    arc.strokeColor = [UIColor purpleColor].CGColor;
    arc.lineWidth = 15;

    [self.view.layer addSublayer:arc];

    CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    drawAnimation.duration            = 5.0; // "animate over 10 seconds or so.."
    drawAnimation.repeatCount         = 1.0;  // Animate only once..
    drawAnimation.removedOnCompletion = NO;   // Remain stroked after the animation..
    drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
    drawAnimation.toValue   = [NSNumber numberWithFloat:10.0f];
    drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    [arc addAnimation:drawAnimation forKey:@"drawCircleAnimation"];

}

结果如下:

我的问题是:如果值

渐变看起来像这样:

任何帮助将不胜感激!

非常感谢。

花岗岩

【问题讨论】:

    标签: ios xcode uicolor uibezierpath


    【解决方案1】:

    您可以使用 CAGradientLayer 来获得渐变效果,并使用 CAShapeLayer 作为蒙版。

    例如:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        int radius = 100;
    
        CAShapeLayer *arc = [CAShapeLayer layer];    
        arc.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 50) radius:radius startAngle:60.0 endAngle:0.0 clockwise:YES].CGPath;
    
        arc.position = CGPointMake(CGRectGetMidX(self.view.frame)-radius,
                                   CGRectGetMidY(self.view.frame)-radius);
    
        arc.fillColor = [UIColor clearColor].CGColor;
        arc.strokeColor = [UIColor purpleColor].CGColor;
        arc.lineWidth = 15; 
        CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
        drawAnimation.duration            = 5.0; // "animate over 10 seconds or so.."
        drawAnimation.repeatCount         = 1.0;  // Animate only once..
        drawAnimation.removedOnCompletion = NO;   // Remain stroked after the animation..
        drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
        drawAnimation.toValue   = [NSNumber numberWithFloat:10.0f];
        drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
        [arc addAnimation:drawAnimation forKey:@"drawCircleAnimation"];
    
        CAGradientLayer *gradientLayer = [CAGradientLayer layer];
        gradientLayer.frame = self.view.frame;
        gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,(__bridge id)[UIColor blueColor].CGColor ];
        gradientLayer.startPoint = CGPointMake(0,0.5);
        gradientLayer.endPoint = CGPointMake(1,0.5);
    
        [self.view.layer addSublayer:gradientLayer];
         //Using arc as a mask instead of adding it as a sublayer.
         //[self.view.layer addSublayer:arc]; 
         gradientLayer.mask = arc;
    
    
    }
    

    【讨论】:

    • 这看起来不像是会沿着路径绘制,而是似乎会绘制一个水平渐变,这是由路径显示的。那有意义吗?你如何“弯曲”水平渐变以跟随一个完整的圆圈?
    • drawAnimation.toValue = [NSNumber numberWithFloat:10.0f]; 是什么意思?为什么是 10.0f?
    【解决方案2】:

    要沿笔划绘制渐变,请参阅此实现:https://stackoverflow.com/a/43668420/917802

    编辑: 简而言之,创建一个自定义 UIView 类,通过以增加的角度在两种颜色之间迭代来为其添加径向渐变,例如colour1 = 1 度, colour2 = 2 度​​等,一直到 360。然后应用一个甜甜圈蒙版。当您更改遮罩 CAShapeLayer 的 strokeEnd 值时,您也会旋转底层的径向渐变。因为它们一起移动,所以看起来笔画本身具有渐变。

    【讨论】:

      【解决方案3】:

      到目前为止给出的答案都很棒,但是有点复杂,我认为下面的逻辑应该简单得多:

      1. 绘制形状层的曲线/路径。
      2. 自行关闭路径,即绘制相同的曲线/路径,但反向。
      3. 创建一个 CAShapeLayer 并将其路径设置为 (2) 中的路径。
      4. 为 (3) 中的形状图层赋予任意笔触颜色。
      5. 创建一个 CAGradientLayer。
      6. 将渐变图层蒙版设置为(4)中的形状图层。
      7. 将渐变层的颜色设置为所需的数组。
      8. 将渐变层添加到 (1) 中的原始 shapeLayer。
      func draweCurve(fromPoint: CGPoint, toPoint: CGPoint, x: CGFloat) {
          // ------- 1 --------
          let curveLayer = CAShapeLayer()
          curveLayer.contentsScale = UIScreen.main.scale
          curveLayer.frame = CGRect(origin: .zero, size: CGSize(width: 100, height: 100))
          curveLayer.fillColor = UIColor.red.cgColor
          curveLayer.strokeColor = UIColor.blue.cgColor
      
          let path = UIBezierPath()
          path.move(to: fromPoint)
          let controlPoint1 = CGPoint(x: fromPoint.x + 40 * 0.45, y: fromPoint.y)
          let controlPoint2 = CGPoint(x: toPoint.x - 40 * 0.45, y: toPoint.y)
          path.addCurve(to: toPoint, controlPoint1: controlPoint1, controlPoint2: controlPoint2)
          curveLayer.path = path.cgPath
      
          // ------- 2 --------
          // close the path on its self
          path.addCurve(to: fromPoint, controlPoint1: controlPoint2, controlPoint2: controlPoint1)
          addGradientLayer(to: curveLayer, path: path)
      }
      
      private func addGradientLayer(to layer: CALayer, path: UIBezierPath) {
          // ------- 3 --------
          let gradientMask = CAShapeLayer()
          gradientMask.contentsScale = UIScreen.main.scale
          // ------- 4 --------
          gradientMask.strokeColor = UIColor.white.cgColor
          gradientMask.path = path.cgPath
      
          // ------- 5 --------
          let gradientLayer = CAGradientLayer()
          // ------- 6 --------
          gradientLayer.mask = gradientMask
          gradientLayer.frame = layer.frame
          gradientLayer.contentsScale = UIScreen.main.scale
          // ------- 7 --------
          gradientLayer.colors = [UIColor.gray.cgColor, UIColor.green.cgColor]
          // ------- 8 --------
          layer.addSublayer(gradientLayer)
      }
      

      【讨论】:

        猜你喜欢
        • 2014-01-07
        • 1970-01-01
        • 2019-03-14
        • 1970-01-01
        • 1970-01-01
        • 2022-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多