关于CAShapeLayer的一些实用案例和技巧

一、使用CAShapeLayer实现复杂的View的遮罩效果

1.1、案例演示

最近在整理一个聊天的项目的时候,发送图片的时候,会有一个三角的指向效果,指向这张图片的发送者。服务端返回给我们的图片只是一张矩形的图片,我们如何把一张矩形的图片或者View,加上一层自定义遮罩效果,就是本文要讲的内容。效果演示如下:第一张是一个View的遮罩效果,第二张是UIImageView的遮罩效果。

演示图片

1.2、实现机制

在每一View的layer层中有一个mask属性,他就是专门来设置该View的遮罩效果的。该mask本身也是一个layer层。我们只需要生成一个自定义的layer,然后覆盖在需要遮罩的View上面即可。问题就归于如何生成入上图所示的不规则图片的Layer。CAShapeLayer可以根据几个点的依次连线,产生一个闭合空间的layer。如下图所示:

1.3、实现代码

实现方式为实现了CAShapeLayer的ViewMask的Category。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

@implementation CAShapeLayer (ViewMask)

+ (instancetype)createMaskLayerWithView : (UIView *)view{

    CGFloat viewWidth = CGRectGetWidth(view.frame);

    CGFloat viewHeight = CGRectGetHeight(view.frame);

    CGFloat rightSpace = 10.;

    CGFloat topSpace = 15.;

    CGPoint point1 = CGPointMake(0, 0);

    CGPoint point2 = CGPointMake(viewWidth-rightSpace, 0);

    CGPoint point3 = CGPointMake(viewWidth-rightSpace, topSpace);

    CGPoint point4 = CGPointMake(viewWidth, topSpace);

    CGPoint point5 = CGPointMake(viewWidth-rightSpace, topSpace+10.);

    CGPoint point6 = CGPointMake(viewWidth-rightSpace, viewHeight);

    CGPoint point7 = CGPointMake(0, viewHeight);

    UIBezierPath *path = [UIBezierPath bezierPath];

    [path moveToPoint:point1];

    [path addLineToPoint:point2];

    [path addLineToPoint:point3];

    [path addLineToPoint:point4];

    [path addLineToPoint:point5];

    [path addLineToPoint:point6];

    [path addLineToPoint:point7];

    [path closePath];

    CAShapeLayer *layer = [CAShapeLayer layer];

    layer.path = path.CGPath;

    return layer;

}

@end

1.4、调用方式


1

2

3

4

5

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(40, 50, 80, 100)];

view.backgroundColor = [UIColor orangeColor];

[self.view addSubview:view];

CAShapeLayer *layer = [CAShapeLayer createMaskLayerWithView:view];

view.layer.mask = layer;

二、使用CAShapeLayer实现一个音量大小动态改变的控件

2.1、案例演示

对于实时显示语音音量大小的需求,发现很多人的实现方式通过预放置多张图进行切换进行完成的。这样的处理,不但会浪费App的资源存储空间,而且效率也不高。对于符合某一定规律动态改变的图形,我们也可以考虑通过代码的方式来实现。

2.2、实现机制

外部轮廓View主要控制显示大小和显示的圆角效果。内部的Layer主要控制动态显示的高度,虽然他是矩形的。但是当把该Layer加入到View中,而该View设置了_dynamicView.clipsToBounds = YES;。内部的Layer超过外部轮廓的部分,则会被切除掉。

如此说来,我们只需要动态改变内部Layer显示的高度,即可完成该效果显示。是不是很简单啊。。

2.3、实现代码

_dynamicView 表示外部轮廓的View。

indicateLayer 表示内容动态显示的Layer。

实现动态改变的函数如下:


1

2

3

4

5

6

7

8

9

10

-(void)refreshUIWithVoicePower : (NSInteger)voicePower{

    CGFloat height = (voicePower)*(CGRectGetHeight(_dynamicView.frame)/TOTAL_NUM);

    [_indicateLayer removeFromSuperlayer];

    _indicateLayer = nil;

    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, CGRectGetHeight(_dynamicView.frame)-height, CGRectGetWidth(_dynamicView.frame), height) cornerRadius:0];

    _indicateLayer = [CAShapeLayer layer];

    _indicateLayer.path = path.CGPath;

    _indicateLayer.fillColor = [UIColor whiteColor].CGColor;

    [_dynamicView.layer addSublayer:_indicateLayer];

}

三、圆形进度条

3.1、案例演示

最近有一个小需求,就是要做一个圆形进度条,大概样子如下:

在不知道有CAShapeLayer的strokeStart和strokeEnd属性的时候,我采取的方法就是实时的 移除旧的CAShapeLayer 然后重绘这个圆形的CAShapeLayer。显然这种方式的效率是不高的。后来在一次看别人Demo的时候,发现别人使用了CAShapeLayer的strokeStart和strokeEnd属性,实现这一个效果十分的简单方便。下面就和大家来讲一讲这两个属性的使用。

3.2、属性详解

苹果官方给出这两个属性的解释为:

/* These values define the subregion of the path used to draw the

stroked outline. The values must be in the range [0,1] with zero

representing the start of the path and one the end. Values in

between zero and one are interpolated linearly along the path

length. strokeStart defaults to zero and strokeEnd to one. Both are

animatable. */

大概意思就是:我们可以对绘制的Path进行分区。这两个属性的值在0~1之间,0代表Path的开始位置,1代表Path的结束位置。是一种线性递增关系。strokeStart默认值为0,strokeEnd默认值为1。这两个属性都支持动画。


1

2

3

4

5

6

7

8

9

10

CAShapeLayer *shapeLayer = [CAShapeLayer layer];

shapeLayer.frame = _demoView.bounds;

shapeLayer.strokeEnd = 0.7f;

shapeLayer.strokeStart = 0.1f;

UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:_demoView.bounds];

shapeLayer.path = path.CGPath;

shapeLayer.fillColor = [UIColor clearColor].CGColor;

shapeLayer.lineWidth = 2.0f;

shapeLayer.strokeColor = [UIColor redColor].CGColor;

[_demoView.layer addSublayer:shapeLayer];

我们通过以上代码设置:strokeStart=0.1f; strokeEnd=0.7f则显示如下图所示。

3.3、圆形进度条的实现代码


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

CAShapeLayer *shapeLayer = [CAShapeLayer layer];

shapeLayer.frame = _demoView.bounds;

UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:_demoView.bounds];

shapeLayer.path = path.CGPath;

shapeLayer.fillColor = [UIColor clearColor].CGColor;

shapeLayer.lineWidth = 2.0f;

shapeLayer.strokeColor = [UIColor redColor].CGColor;

[_demoView.layer addSublayer:shapeLayer];

CABasicAnimation *pathAnima = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];

pathAnima.duration = 3.0f;

pathAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

pathAnima.fromValue = [NSNumber numberWithFloat:0.0f];

pathAnima.toValue = [NSNumber numberWithFloat:1.0f];

pathAnima.fillMode = kCAFillModeForwards;

pathAnima.removedOnCompletion = NO;

[shapeLayer addAnimation:pathAnima forKey:@"strokeEndAnimation"];

时间: 2024-12-21 09:04:30

关于CAShapeLayer的一些实用案例和技巧的相关文章

信盈达分享给你一些实用的Linux技巧

首先,我想告诉大家,在Unix/Linux下,最有效率技巧的不是操作图形界面,而是命令行操作,因为命令行意味着自动化.如果你看过<你可能不知道的Shell>以及<28个Unix/Linux的命令行神器>你就会知道Linux有多强大,这个强大完全来自于命令行,于是,就算你不知道怎么去做一个环保主义的程序员 ,至少他们可以让你少熬点夜,从而有利于你的身体健康.下面是一个有点长的列表,正如作者所说,你并不需要知道所有的这些东西,但是如果你还在很沉重地在使用Linux的话,这些东西都值得你

SQL Delta实用案例介绍,很好的东西,帮了我不少忙

SQL Delta实用案例介绍 概述 本篇文章主要介绍SQL DELTA的简单使用.为了能够更加明了的说明其功能,本文将通过实际项目中的案例加以介绍. 主要容 ?   SQL DELTA 简介 ?   创建SQL DELTA项目 ?   使用SQLDELTA 进行数据库结构同步 ?   使用SQLDELTA进行数据库数据同步 ?   生成数据报表 ?   待续 SQLDELTA简介 SQLDELTA是一款便捷实用的数据库管理工具.使用它可以找到现在数据库项目与过去数据库的异同点.并可以使你的产品

精选19款华丽的HTML5动画和实用案例

下面是本人收集的19款超酷HTML5动画和实用案例,觉得不错,分享给大家. 1.HTML5 Canvas火焰喷射动画效果 还记得以前分享过的一款HTML5烟花动画HTML5 Canvas烟花特效,今天我们要来分享一款类似的HTML5动画效果,一款基于HTML5 Canvas火焰喷射动画.用鼠标拖动一条直线,直线长度表示火焰喷射的力度,另外,火焰在运动中还可以反射效果哦. 在线演示        源码下载 2.HTML5 3D立方体旋转动画 之前我们已经分享一款HTML5 3D正方体旋转动画,可以

jquery,tree无限级树形菜单+简单实用案例

jquery,tree无限级树形菜单+简单实用案例 我在项目中用到产品类别的树形.各种地方都要用. 我就封装起来,方便以后调用. 记录下来,希望给新手们提供帮助.要记得导入jquery.js  tree.js 哦 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri=&quo

10个实用Eclipse调试技巧

Eclipse是众多Java程序员实用的开发工具,其中开发技巧也是繁多,但作为优秀的Java程序员,需要掌握最起码的调试技巧. 小编从前辈程序员和网络中,整理了10个Eclipse调试技巧,希望对Java程序员有用. 1 条件断点 如果你不知道如何添加断点,只需点击左边面板(行号前面)断点即被创建.在调试界面中,"断点"视图会把所有被创建的断点列出来.我们可以给它加一个布尔条件,也就是说,该断点会被激活并且如果布尔条件为真,就会执行该断点,否则将会跳过往下执行. 2 异常断点 在断点视

JAVA实用案例之文件导出(JasperReport踩坑实录)

写在最前面 想想来新公司也快五个月了,恍惚一瞬间. 翻了翻博客,因为太忙,也有将近五个多月没认真总结过了. 正好趁着今天老婆出门团建的机会,记录下最近这段时间遇到的大坑-JasperReport. 六月份的时候写过一篇利用poi文件导入导出的小Demo,JAVA实用案例之文件导入导出(POI方式). 虽然简单,但是企业应用的原理基本上也就是这样,只不过是封装的更好些,不像我之前写的那样每个Cell都需要定义,其实poi的方式也是我目前最推崇的方式之一了.主要原因是jxl不支持xlsx,Jaspe

分享《机器学习:实用案例解析》中文版PDF+英文版PDF+源代码

下载:https://pan.baidu.com/s/1-TzAIfMvJosL9-vk5Ft5kQ 更多资料分享:http://blog.51cto.com/3215120 <机器学习:实用案例解析>中文版PDF+英文版PDF+源代码R语言版的机器学习:中文版PDF,302页,带目录和书签:英文版PDF,322页,带目录和书签:配套源代码. 中文版如图所示: 原文地址:http://blog.51cto.com/3215120/2313183

掌握这3个实用的Word技巧,快速提高工作效率和加班说拜拜!

在日常工作中,我们经常会用到Word文档.你知道哪些关于Word的实用技巧呢?今天给大家分享3个非常实用的Word技巧,希望能够帮助大家提高工作效率! 快速标记文本内容 按快捷键"Ctrl+H"弹出查找和替换框,点击"查找",在"查找内容"框输入标记内容即可. 具体操作如下: 快速建立各页标题 先输入标题,然后选中文本打开"段落设置",在换行和分页栏下选择"段前分页",点击菜单栏"视图"

基于TP5.1实用案例及教程

推荐<基于TP5.1实用案例及教程>书 目录: 通用封装 Export通用封装Import通用封装配合Import通用封装的ImportBaseVerify类Files通用封装Directory通用封装Pdf通用封装Words通用封装Nredis(redis封装)ZipArchives压缩zip文件封装BarQrcode条形码二维码Publics公共方法封装Curls(cUrl请求封装) extend扩展开发 何时编写扩展文件包扩展文件包如何编写 题外话 常用的compose安装一些建议及细节