iOS  Mask属性的详细介绍及应用实例

所属分类: 软件编程 / IOS 阅读数: 1016
收藏 0 赞 0 分享

前言:

在开发过程中,类似android和其他平台的UI开发方法,需要通过一个mask图显示部分UI或者Icon资源。ios的控件自带alpha的值,但是这个值都是整个icon或者UI的透明效果,不能做到自定义的透明或者镂空效果。我们必须借助于mask资源图。

Mask属性介绍

Mask平时用的最多的是masksToBounds 吧. 其实除此以外Mask使用场景很多,看完之后你会发现好真是好用的不要不要的...

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

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

图1

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

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

图2

 

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 的位置就能看到我们所要的效果文字颜色渐变. 下左图设置了Mask , 下右图未设置Mask.

 

- (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;
}

源码可以进github查看: https://github.com/xl20071926/LXGradientProcessView 

另外还有类似的仿照芝麻信用,用Mask和CAShaperLayer 做的,有兴趣的也可以看下:https://github.com/xl20071926/LXCircleAnimationView

 实例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;

顺便提下,在实际开发中可能遇到这种需求,当tableView 滑动到某个位置的时候才显示新手引导.

这时候就需要将tableView上的坐标转化为相对于屏幕的坐标.  可用原生的方法:

- (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;

- (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

更多精彩内容其他人还在看

IOS开发相册图片多选和删除的功能

之前小编有和大家分享过一篇关于从相册选取单张照片的文章,那么下面这篇文章跟大家分享下如何相册多图选择和删除,以及包括拍照功能,有需要的可以参考学习,下面来一起看看吧。
收藏 0 赞 0 分享

iOS使用runtime修改文本框(TextField)的占位文字颜色

相信大家都知道TextField默认的占位颜色也是深灰色,这个颜色比较难看清,这篇文章给大家介绍如何使用runtime修改TextField文本框的占位文字颜色,有需要的可以参考借鉴.
收藏 0 赞 0 分享

iOS实现点击状态栏自动回到顶部效果详解

在IOS开发过程中,经常会有这种需求,需要通过点击状态栏返回到顶部,给用户更好的体验效果,下面这篇文章给大家详细介绍了实现过程,有需要的可以参考借鉴。
收藏 0 赞 0 分享

IOS上iframe的滚动条失效的解决办法

这篇文章主要为大家详细介绍了IOS上iframe的滚动条失效的解决办法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

IOS面试大全之常见算法

之前看了很多面试题,感觉要不是不够就是过于冗余,于是我将网上的一些面试题进行了删减和分类,这篇文章先给大家分享一下IOS中的常见算法,有需要的可以参考借鉴。
收藏 0 赞 0 分享

IOS判断字符串是否有空格实例

在我们大家日常开发的时候,经常会需要对注册,登录,忘记密码等功能的密码进行判断是否包含空格,下面这篇文章给大家分享了自己封装的一个方法,有需要的可以参考借鉴。
收藏 0 赞 0 分享

IOS设置按钮为圆角的示例代码

这篇文章给大家分享了IOS按钮设置为圆角的方法,按钮的四个角都可随意设置为圆角,对大家开发IOS具有一定的参考借鉴价值。有需要的朋友们可以参考借鉴。
收藏 0 赞 0 分享

IOS绘制虚线的方法总结

这篇文章给大家分享了iOS中绘制虚线常见的几种方式,大家可以根据自己的需求进行选择哪种方法,下面跟着小编来一起看看吧。
收藏 0 赞 0 分享

React Native搭建iOS开发环境

React Native的门槛不管是对于前端开发者还是移动端开发者来说都是很高的,既要懂原生又要懂js,技术栈是相当长的。但是没有关系,下面我们一步步来学习,慢慢成长吧!
收藏 0 赞 0 分享

IOS轻松几步实现自定义转场动画

这篇文章将讲述几个步骤实现转场动画的自定义方式,并且给出了示例代码,毕竟代码才是我们的语言,这样比较容易上手。下面来一起看看吧。
收藏 0 赞 0 分享
查看更多