美文网首页
iOS 巧用Mask属性之绘制渐变进度条 & 镂空效果

iOS 巧用Mask属性之绘制渐变进度条 & 镂空效果

作者: 半岛夏天 | 来源:发表于2018-11-28 22:09 被阅读22次

    先来了解下Mask属性到底是什么?

    Mask 英文解释是蒙板/面罩,平时我们称为蒙层. 在苹果官方文档里如下图,意思是Mask是一个可选的Layer,它可以是根据透明度来掩盖Layer的内容.

    这么一说好像...还是不晓得有什么卵用...

    那再看下面这个说明,意思是Layer的透明度决定了Layer内容是否可以显示,非透明的内容和背景可以显示,透明的则无法显示.

    Mask 实例使用

    实例1:渐变进度条

    先看"脸" 再谈"内涵"

    整个动画效果主要可以分成4步骤:

    1.创建一个CALayer 做为背景色进度条

    CALayer *bgLayer = [CALayer layer];
    
    bgLayer.frame = CGRectMake(kNumberMarkWidth / 2, self.numberMarkView.bottom + 10.f, self.width - kNumberMarkWidth / 2, kProcessHeight);
    
    bgLayer.backgroundColor = [UIColor colorWithHex:0xF5F5F5].CGColor;
    
    bgLayer.masksToBounds = YES;
    
    bgLayer.cornerRadius = kProcessHeight / 2;
    
    [self.layer addSublayer:bgLayer];
    

    2.创建一个CAGradientLayer 渐变效果的Layer

    self.gradientLayer =  [CAGradientLayer layer];
    self.gradientLayer.frame = bgLayer.frame;
    self.gradientLayer.masksToBounds = YES;
    self.gradientLayer.cornerRadius = kProcessHeight / 2;
      // 设置渐变颜色数组
    [self.gradientLayer setColors:[NSArray arrayWithObjects:
                                   (id)[[UIColor colorWithHex:0xFF6347] CGColor],
                                   [(id)[UIColor colorWithHex:0xFFEC8B] CGColor],
                                   (id)[[UIColor colorWithHex:0xEEEE00] CGColor],
                                   (id)[[UIColor colorWithHex:0x7FFF00] CGColor],
                                   nil]];
      // 设置渐变位置数组
    [self.gradientLayer setLocations:@[@0.3, @0.5, @0.7, @1]];
      // 设置渐变开始和结束位置
    [self.gradientLayer setStartPoint:CGPointMake(0, 0)];
    [self.gradientLayer setEndPoint:CGPointMake(1, 0)];
    

    3.创建一个Mask Layer,并设置为CAGradientLayer渐变层的Mask. 然后通过设置maskLayer 宽度来控制进度了. 是不是很简单,不过好像没有感觉不出Mask的强大之处...

    self.maskLayer = [CALayer layer];
    self.maskLayer.frame = CGRectMake(0, 0, (self.width - kNumberMarkWidth / 2) * self.percent / 100.f, kProcessHeight);
    [self.gradientLayer setMask:self.maskLayer];
    
    - (void)circleAnimation { // 进度条动画
        [CATransaction begin];
        [CATransaction setDisableActions:NO];
        [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
        [CATransaction setAnimationDuration:kAnimationTime];
        self.maskLayer.frame = CGRectMake(0, 0, (self.width - kNumberMarkWidth / 2) * _percent / 100.f, kProcessHeight);
        [CATransaction commit];
    }
    

    4.文字渐变,这个就能看出Mask 的特点了.

    先创建一个Label展示分数,再同第2步创建一个一样的渐变CAGradientLayer.**将Label的关联图层设置为渐变CAGradientLayer 的Mask, **这样就OK了.

    上面有说过Mask属性特点是内容非透明则可以显示,透明则隐藏.

    实例中,Label做为渐变层的Mask, Label中文字部分是非透明的,其他是透明的.那么文字和文字背景(这里就是渐变层)可以显示.大概就像镂空文字部分,然后显示出底下的渐变层.

    最后只要移动Label 的位置就能看到我们所要的效果文字颜色渐变. 下图1设置了Mask , 下图2未设置Mask.

    图1 图2
    - (void)setNUmberMarkLayer { // 提示文字设置渐变色
        
        CAGradientLayer *numberGradientLayer = [CAGradientLayer layer];
        numberGradientLayer.frame = CGRectMake(0, kTopSpaces, self.width, kNumberMarkHeight);
        [numberGradientLayer setColors:self.colorArray];
        [numberGradientLayer setLocations:self.colorLocationArray];
        [numberGradientLayer setStartPoint:CGPointMake(0, 0)];
        [numberGradientLayer setEndPoint:CGPointMake(1, 0)];
        [self.layer addSublayer:numberGradientLayer];
        [numberGradientLayer setMask:self.numberMark.layer];
        self.numberMark.frame = numberGradientLayer.bounds;
    }
    

    埋点->此地无银三百两...

    实例2:镂空效果

    新手引导大多数app都会有这个功能,然而据了解蛮多就是直接贴张图片上面就搞定了.

    额,这样做确实简单,可是这样好Low而且做出来的效果不好,那我们来用逼格高点的镂空方式实现:

    先来一个简单的效果图:

    实现起来也很简单,主要分3个步骤:

    1.创建一个镂空的路径:

    UIBezierPath 有个原生的方法- (void)appendPath:(UIBezierPath *)bezierPath, 这个方法作用是俩个路径有叠加的部分则会镂空.

    这个方法实现原理应该是path的FillRule 默认是FillRuleEvenOdd(CALayer 有一个fillRule属性的规则就有kCAFillRuleEvenOdd), 而EvenOdd 是一个奇偶规则,奇数则显示,偶数则不显示.叠加则是偶数故不显示.

    2.创建CAShapeLayer 将镂空path赋值给shapeLayer

    3.将shapeLayer 设置为背景视图的Mask

    UIView *backgroundView = [[UIView alloc] init];
    backgroundView.frame = self.view.bounds;
    backgroundView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.7];
    [self.view addSubview:backgroundView];
    // 创建一个全屏大的path
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.view.bounds];
    // 创建一个圆形path
    UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.view.center.x, self.view.center.y - 25)
                                                              radius:50
                                                          startAngle:0
                                                            endAngle:2 * M_PI
                                                           clockwise:NO];
    [path appendPath:circlePath];
    
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.path = path.CGPath;
    backgroundView.layer.mask = shapeLayer;
    

    未完待续...

    相关文章

      网友评论

          本文标题:iOS 巧用Mask属性之绘制渐变进度条 & 镂空效果

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