iOS 绘制渐变·实例篇

作者: QiShare | 来源:发表于2018-10-25 13:32 被阅读342次

    级别: ★★☆☆☆
    标签:「iOS颜色渐变」「CAGradientLayer渐变」「CAGradientLayer」
    作者: Xs·H
    审校: QiShare团队

    iOS 绘制渐变·基础篇的基础上,CAGradientLayer配合CAShapeLayer可以实现很多渐变效果。本文列举三个,并附上实现思路。

    1、渐变色进度条
    • 渐变色进度条实现效果
    渐变色进度条
    • 渐变色进度条实现代码
    // 进度条view
    UIView *progressView = [[UIView alloc] initWithFrame:CGRectMake(30.0, 100.0, self.view.bounds.size.width - 30.0 * 2, 5.0)];
    progressView.center = (CGPoint){self.view.bounds.size.width / 2, self.view.bounds.size.height / 3};
    progressView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
    progressView.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:.3];
    progressView.layer.cornerRadius = progressView.bounds.size.height / 2;
    progressView.layer.masksToBounds = YES;
    [self.view addSubview:progressView];
    
    // 渐变色layer
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = progressView.bounds;
    gradientLayer.colors = @[(__bridge id)[[UIColor greenColor] colorWithAlphaComponent:1.0].CGColor,
                             (__bridge id)[[UIColor blueColor] colorWithAlphaComponent:1.].CGColor,
                             (__bridge id)[[UIColor purpleColor] colorWithAlphaComponent:1.0].CGColor,];
    gradientLayer.startPoint = (CGPoint){.0};
    gradientLayer.endPoint = (CGPoint){1.0};
    [progressView.layer addSublayer:gradientLayer];
    
    // mask layer
    CALayer *maskLayer = [CALayer layer];
    maskLayer.frame = (CGRect){.0, .0, .0, gradientLayer.bounds.size.height};
    maskLayer.backgroundColor = [UIColor whiteColor].CGColor;
    gradientLayer.mask = maskLayer;
    
    // 设置变化规则
    CGFloat deltaWidth = gradientLayer.bounds.size.width / 60;
    [NSTimer scheduledTimerWithTimeInterval:.1 repeats:YES block:^(NSTimer * _Nonnull timer) {
        CGRect rect = maskLayer.bounds;
        rect.size.width += deltaWidth;
        maskLayer.frame = rect;
        if (gradientLayer.bounds.size.width - maskLayer.bounds.size.width < deltaWidth) {
            [timer invalidate];
        }
    }];
    
    • 渐变色进度条实现思路
      1)创建progressView,设置浅灰色,切圆角,作为progress0时的状态;
      2)创建gradientLayer,设置渐变色,左右均匀渐变,覆盖到progressView.layer上面,作为progress1时的状态;
      3)创建maskLayer,设置非透明色,赋值给gradientLyaer.mask,作为progress变化时的状态。
      4)定时改变maskLayerwidth,通过maskLayerwidthgradientLayer重合部分来控制progress

    PS:layer.masklayer的非透明色重合部分才会被显示出来。

    用同样的思路,也可以做出反向的进度条,效果如下:

    渐变色进度条-反向
    2、渐变色圆框
    • 渐变色圆框实现效果
    渐变色圆框
    • 渐变色圆框实现代码
    // 圆框所在区域View
    UIView *arcView = [[UIView alloc] initWithFrame:CGRectMake(.0, .0, 300.0, 300.0)];
    arcView.center = (CGPoint){self.view.bounds.size.width / 2, self.view.bounds.size.height / 3};
    arcView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
    [self.view addSubview:arcView];
    
    // 渐变色 layer
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = arcView.bounds;
    gradientLayer.colors = @[(__bridge id)[[UIColor redColor] colorWithAlphaComponent:1.0].CGColor,
                             (__bridge id)[[UIColor greenColor] colorWithAlphaComponent:1.0].CGColor,
                             (__bridge id)[[UIColor blueColor] colorWithAlphaComponent:1.0].CGColor];
    gradientLayer.startPoint = CGPointMake(.0, .0);
    gradientLayer.endPoint = CGPointMake(.0, 1.0);
    [arcView.layer addSublayer:gradientLayer];
    
    // 图形绘制 layer
    CGFloat lineWidth = 10.0;
    CGFloat rectSide = arcView.bounds.size.width - lineWidth;
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:(CGRect){lineWidth / 2, lineWidth / 2, rectSide, rectSide}];
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.path = path.CGPath;
    shapeLayer.fillColor = [UIColor clearColor].CGColor;
    shapeLayer.strokeColor = [UIColor whiteColor].CGColor;
    shapeLayer.lineWidth = lineWidth;
    gradientLayer.mask = shapeLayer;
    
    • 渐变色圆框实现思路
      1)创建arcView,确定渐变色圆框所在的区域;
      2)创建gradientLayer,设置渐变色,上下均匀渐变,覆盖到arcView.layer上面;
      3)创建shapeLayer,设置fillColor为透明色,设置strokeColor为非透明色,设置合适的lineWidth
      4)创建bezierPath(path),根据lineWidth设置绘制区域,赋值给shapeLayer.path
      5)将shapeLayer赋值给gradientLayer.mask,控制显示出的圆框区域;

    PS:圆框绘制可以理解成用圆规画圆,lineWidth表示圆规笔尖的宽度,rectSide表示笔尖中心放置的位置,strokerColor表示笔尖的颜色,fillColor表示闭合圆框内部的填充色。

    3、渐变色弧段
    • 渐变色弧段实现效果
    渐变色弧段
    • 渐变色弧段实现代码
    // 弧段所在区域view
    UIView *arcView = [[UIView alloc] initWithFrame:CGRectMake(.0, .0, 300.0, 300.0)];
    arcView.center = (CGPoint){self.view.bounds.size.width / 2, self.view.bounds.size.height / 3};
    arcView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
    [self.view addSubview:arcView];
    
    // 左侧渐变色 layer
    CAGradientLayer *gradientLayerLeft = [CAGradientLayer layer];
    gradientLayerLeft.frame = CGRectMake(.0, .0, arcView.bounds.size.width / 2, arcView.bounds.size.height);
    gradientLayerLeft.colors = @[(__bridge id)[[UIColor yellowColor] colorWithAlphaComponent:1.0].CGColor,
                                 (__bridge id)[[UIColor greenColor] colorWithAlphaComponent:1.0].CGColor];
    gradientLayerLeft.locations = @[@(.0), @(.67)];
    gradientLayerLeft.startPoint = CGPointMake(.0, .0);
    gradientLayerLeft.endPoint = CGPointMake(.0, 1.0);
    [arcView.layer addSublayer:gradientLayerLeft];
    
    // 右侧渐变色 layer
    CAGradientLayer *gradientLayerRight = [CAGradientLayer layer];
    gradientLayerRight.frame = CGRectMake(arcView.bounds.size.width / 2.0, .0, arcView.bounds.size.width / 2, arcView.bounds.size.height);
    gradientLayerRight.colors = @[(__bridge id)[[UIColor yellowColor] colorWithAlphaComponent:1.0].CGColor,
                                  (__bridge id)[[UIColor redColor] colorWithAlphaComponent:1.0].CGColor];
    gradientLayerRight.locations = @[@(.0), @(.67)];
    gradientLayerRight.startPoint = CGPointMake(.0, .0);
    gradientLayerRight.endPoint = CGPointMake(.0, 1.0);
    [arcView.layer addSublayer:gradientLayerRight];
    
    // 弧段绘制 layer
    CGFloat lineWidth = 10.0;
    CGFloat rectSide = arcView.bounds.size.width - lineWidth;
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(arcView.bounds.size.width / 2, arcView.bounds.size.height / 2) radius:rectSide / 2 startAngle:-7.0 / 6 * M_PI endAngle:-11.0 / 6 * M_PI clockwise:YES];
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.path = path.CGPath;
    shapeLayer.fillColor = [UIColor clearColor].CGColor;
    shapeLayer.strokeColor = [UIColor whiteColor].CGColor;
    shapeLayer.lineWidth = lineWidth;
    shapeLayer.lineCap = @"round";
    arcView.layer.mask = shapeLayer;
    
    • 渐变色弧段实现思路
      1)创建arcView,确定渐变色弧段所在的区域;
      2)创建左侧的gradientLayer,设置渐变色,上下均匀渐变,覆盖到arcView.layer上面;
      3)创建右侧的gradientLayer,设置渐变色,上下均匀渐变,覆盖到arcView.layer上面;
      4)创建shapeLayer,设置fillColor为透明色,设置strokeColor为非透明色,设置合适的lineWidth
      4)创建bezierPath(path),根据lineWidth设置绘制区域,赋值给shapeLayer.path
      5)将shapeLayer赋值给arcView.mask,控制显示出的弧段区域;

    PS:贝塞尔曲线的的角度规则为:从圆心开始,水平向右的弧度为0,顺时针弧度变大,逆时针弧度变小,水平向左为π

    以上渐变色绘制实例的源码可从工程QiGradientLayer中获取。

    关注我们的途径有:
    QiShare(简书)
    QiShare(掘金)
    QiShare(知乎)
    QiShare(GitHub)
    QiShare(CocoaChina)
    QiShare(StackOverflow)
    QiShare(微信公众号)

    推荐文章:
    奇舞周刊279期

    相关文章

      网友评论

        本文标题:iOS 绘制渐变·实例篇

        本文链接:https://www.haomeiwen.com/subject/xusrzftx.html