当前位置: 首页 > 编程日记 > 正文

iOS动画系列之八:使用CAShapeLayer绘画动态流量图

这篇文章通过使用CAShapeLayer和UIBezierPath来画出一个动态显示剩余流量的小动画。

最终实现的效果如下:

Paste_Image.pngPaste_Image.png

动态效果图:

shapeLayerAni.gifshapeLayerAni.gif

1. CAShapeLayer

实际中,能够用CALayer完成的任务是比较少的,如果使用这个基础图层就能实现绝大部分的功能,咱们就没有必要再开启一个CAShapeLayer了嘛。

1.1 CAShapeLayer的优点

那CAShapeLayer到底有啥子优点嘛!

  • CAShapeLayer作为继承自CALayer的子类,当然可使用CALayer的所有属性。也就是说,爹有的它都有了。
  • CAShapeLayer是一个通过矢量图形而不是位图来绘制的图层子类。指定诸如颜色和线宽等属性,用path来定义想要绘制的图形,最后CAShapeLayer就自动渲染出来了。也就是说,CAShapeLayer不需要像普通CALayer一样创建一个寄宿图形。而且是矢量图形噢!!所以无论有多大,都不会占用太多的内存。
  • CAShapeLayer使用了硬件加速,绘制同一图形会比用CoreGraphics快很多。

1.2 基本属性

属性名作用
path图像的绘制路径,path不支持隐式动画
fillColor填充path的颜色,或无填充。默认为不透明黑色。
fillRule填充path的规则。选项是非零和偶奇。默认为非零。
lineCap线端点类型
lineDashPattern线性模版
lineDashPhase线型模版的起点
lineJoin线连接类型
lineWidth线宽
miterLimit最大斜接长度。
strokeColor描边颜色
strokeStart描边的起点
strokeEnd描边的终点

1.3 属性解读

能看到这里,说明您已经不是一个没有任何基础的小白了。所以特别基础的属性就没必要解释一遍了。下面只是一个不常用或者立即起来稍微费点劲的属性。

  • lineDashPattern: 这是一个NSNumber的数组,索引从1开始记,奇数位数值表示实线长度,偶数位数值表示空白长度。系统会按照数值自动重复设置虚线。
  • miterLimit:最大斜接长度。斜接长度指的是在两条线交汇处和外交之间的距离。只有lineJoin属性为kCALineJoinMiter时miterLimit才有效。边角的角度越小,斜接长度就会越大。为了避免斜接长度过长,我们可以使用miterLimit属性。如果斜接长度超过miterLimit的值,边角会以lineJoin的“bevel”即kCALineJoinBevel类型来显示
  • strokeStart & strokeEnd : 描边的起始点位置。范围为0~1.

1.3.1 lineDashPattern画虚线

Paste_Image.pngPaste_Image.png

basicLayer.lineDashPattern = [5,2,10,7]

这句话的意思是说这个虚线由四部分组成:

  1. 第一段实线长度为5
  2. 画完长度为5像素的实线之后,空2像素
  3. 空完2像素之后,再画10像素的实线
  4. 画完长度为10像素的实线之后,空7像素
    然后重复这个数组中的数值,一直不停的绘画。

1.3.2 strokeStart & strokeEnd

strokeStart它表示描线开始的地方占总路径的百分比。默认值是0。
strokeEnd表示绘制结束的地方站总路径的百分比。默认值是1,如果小于等于strokeStart 则绘制不出任何内容。

手画一张图,解释一下啥意思:

Paste_Image.pngPaste_Image.png

2. 实战:绘制一个镂空图层动画

做好后的效果如下:

Paste_Image.pngPaste_Image.png

    fileprivate func hollowLayer(){
//        创建空心的layerlet hollowLayer = CAShapeLayer()hollowLayer.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)view.layer.addSublayer(hollowLayer)hollowLayer.position = view.center//        最外面待圆角的方形pathlet squarePath = UIBezierPath.init(roundedRect: CGRect(x: 0, y: 0, width: 100, height: 100), cornerRadius: 5)
//        中间镂空的圆形pathlet hollowPath = UIBezierPath.init(ovalIn: CGRect(x: 10, y: 10, width: 80, height: 80))squarePath.append(hollowPath)hollowLayer.path = squarePath.cgPathhollowLayer.fillColor = UIColor.lightGray.cgColor
//        设置路径的填充模式为两个图形的非交集hollowLayer.fillRule = kCAFillRuleEvenOdd//        创建进度layerlet processSectorLayer = CAShapeLayer()view.layer.addSublayer(processSectorLayer)processSectorLayer.bounds = CGRect(x: 0, y: 0, width: 70, height: 70)processSectorLayer.position = view.center//        进度的pathlet processSectorPath = UIBezierPath.init(arcCenter: CGPoint.init(x: 35, y: 35), radius: 17.5, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)processSectorLayer.path = processSectorPath.cgPathprocessSectorLayer.lineWidth = 35//        进度的起点和结束位置,设置进度条修改这个值和结束数值就可以了processSectorLayer.strokeStart = 0.5processSectorLayer.strokeEnd = 0.75processSectorLayer.strokeColor = UIColor.lightGray.cgColorprocessSectorLayer.fillColor = UIColor.clear.cgColor}

3. 使用CAShapeLayer绘画动态流量图

有了上面对于CAShapeLayer 的基础训练,绘制一个动态的流量图就不是什么困难的事情了。
实现后的效果如下:

3.1 实现思路

1,创建一个view,用来展示进度圆环。
2,在进度的view上面添加一个layer,用来展示进度圆环底部灰色的圆环。
3,在灰色的圆环上面,添加一个layer,用来显示实际的进度。
4,创建一个定时器,定时器用来更新时时进度。

3.2 代码实现

在文章里面咱们只PO出来一些关键的代码,如果想查看源文件,可以自行下载源码哈。

3.2.1 懒加载进度圆环的shapeLayer

    //   进度条layerlazy var circleProgressLayer: CAShapeLayer = {let circleProgressLayer = CAShapeLayer()let circleBounds = CGRect(x: 0, y: 0, width: 250, height: 250)circleProgressLayer.bounds = circleBoundscircleProgressLayer.position = CGPoint(x: circleBounds.width / 2, y: circleBounds.height / 2)let circleProgressPath = UIBezierPath.init(arcCenter: CGPoint(x: circleBounds.width / 2, y: circleBounds.height / 2), radius: circleBounds.height / 2, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)circleProgressLayer.strokeStart = 0circleProgressLayer.strokeEnd = 1circleProgressLayer.path = circleProgressPath.cgPathcircleProgressLayer.lineWidth = 10circleProgressLayer.strokeColor = UIColor.init(colorLiteralRed: 0, green: 151, blue: 255, alpha: 1).cgColorcircleProgressLayer.fillColor = UIColor.clear.cgColorreturn circleProgressLayer}()

3.2.2 添加定时器

        //开启定时器timer = Timer.scheduledTimer(timeInterval: 0.04, target: self, selector: #selector(progressShowNumber), userInfo: nil, repeats: true)

3.2.3 定时器的调用事件


// 定时器调用的方法@objc private func progressShowNumber(){if progressValue > expectValue - 1 && progressValue < expectValue {timer.invalidate()circleProgressLayer.strokeEnd = expectValue / 100progressLabel.text = "\(expectValue)%"return}if progressValue > expectValue {timer.invalidate()return}//更新进度文字和进度条的strokeEndcircleProgressLayer.strokeEnd = CGFloat(progressValue) / 100progressLabel.text = "\(progressValue)%"progressValue += 1}

这两天人正好在San Francisco,抽空去San Jose苹果的大本营溜达溜达。到时候给大家放照哈。
源代码可以在这里下载。git.oschina.net/atypical/mu…

iOS动画系列之CAShapeLayer(Swift版)

-----------------------华丽分割线,iOS动画系列全集链接-------------------------------------------------
第一篇:iOS动画系列之一:通过实战学习CALayer和透视的原理。做一个带时分秒指针的时钟动画(上)
第二篇:iOS动画系列之二:通过实战学习CALayer和透视的原理。做一个带时分秒指针的时钟动画。包含了OC和Swift两种源代码(下)
第三篇:iOS动画系列之三:Core Animation。介绍了Core Animation的常用属性和方法。
第四篇:CABasic Animation。iOS动画系列之四:基础动画之平移篇
第五篇:CABasic Animation。iOS动画系列之五:基础动画之缩放篇&旋转篇
第六篇:iOS动画系列之六:利用CABasic Animation完成带动画特效的登录界面
第七篇:iOS动画系列之七:实现类似Twitter的启动动画
第八篇:iOS动画系列之八:使用CAShapeLayer绘画动态流量图
第九篇:iOS动画系列之九:实现点赞的动画及播放起伏指示器
第十篇:实战系列:绘制过山车场景


作者:非典型技术宅
链接:https://juejin.im/post/5a01cf166fb9a0450908eb64
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

相关文章:

hiho_1139_二分+bfs搜索

题目 给定N个点和M条边&#xff0c;从点1出发&#xff0c;到达点T。寻找路径上边的个数小于等于K的路径&#xff0c;求出所有满足条件的路径中最长边长度的最小值。 题目链接:二分 最小化最大值&#xff0c;考虑采用二分搜索。对所有的边长进行排序&#xff0c;二分&#x…

Hadoop集群搭建(七:MySQL的安装配置)

实验 目的 要求 目的&#xff1a; 1、掌握MySQL在集群平台中的安装 要求&#xff1a; 完成MySQL的集群版的安装&#xff1b;MySQL集群的相关服务进程能够正常启动&#xff1b;MySQL集群的SQL服务能够作为系统服务开机自动启动&#xff1b;MySQL客户端能够远程连接MySQL集群的…

如何在VMware虚拟机上安装Linux操作系统(Ubuntu)

作为初学者想变为计算机大牛非一朝一夕&#xff0c;但掌握基本的计算机操作和常识却也不是多么难的事情。所以作为一名工科男&#xff0c;为了把握住接近女神的机会&#xff0c;也为了避免当白痴&#xff0c;学会装系统吧&#xff01;of course为避免把自己的电脑作为牺牲品&am…

cf #363 b

B. One Bombtime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard outputYou are given a description of a depot. It is a rectangular checkered field of n  m size. Each cell in a field can be empty (".") or…

swift-video-generator:图片加音频生成视频及多视频合并库及演示

阅读 80收藏 92017-11-07原文链接&#xff1a;github.com腾讯云学生优惠套餐&#xff0c;985高校学习云计算的主力机型&#xff0c;2G2核&#xff0c;1M带宽系统盘&#xff08;Linux 50G/Windows 50G&#xff09;免费赠送50GB对象存储空间还有.cn域名一年使用权&#xff01;不要…

Hadoop集群搭建(八:Hive的安装配置)

实验 目的 要求 目的&#xff1a; &#xff08;1&#xff09;掌握数据仓库工具Hive的安装和配置&#xff1b; 要求&#xff1a; 完成Hive工具的安装和配置&#xff1b;Hive工具能够正常启动运行&#xff1b;Hive控制台命令能够正常使用&#xff1b;能够正常操作数据库、表、…

iOS 富文本编辑工厂, 让书写更简便.

由于最近常用富文本, 在编辑一个富文本时需要操作很多的属性, 书写起来很不方便. 所以我将这些相关属性整理并使用链式方式将它简化了一下. 效果请看下面Demo. 项目工程 实现很简单, 我嘴太笨, 这里就不介绍了, 如有兴趣直接看源码吧. 同时可以通过cocoapods来使用它. pod SJAt…

ORACLE 数据的逻辑组成

数据块&#xff08;block&#xff09;Oracle数据块&#xff08;Data Block&#xff09;是一组连续的操作系统块。分配数据库块大小是在Oracle数据库创建时设置的&#xff0c;数据块是Oracle读写的基本单位。数据块的大小一般是操作系统块大小的整数倍&#xff0c;这样可以避免不…

Java 的zip压缩和解压缩

Java 的zip压缩和解压缩好久没有来这写东西了&#xff0c;今天中秋节&#xff0c;有个东西想拿出来分享&#xff0c;一来是工作中遇到的问题&#xff0c;一来是和csdn问候一下&#xff0c;下面就分享一个Java中的zip压缩技术&#xff0c;代码实现比较简单,代码如下&#xff1a;…

Hadoop集群搭建(九:各服务的启动)

1、查看Zookeeper服务状态&#xff0c;若集群中只有一个"leader"节点&#xff0c; 其余的均为"follower"节点&#xff0c;则集群的工作状态正常 $zkServer.sh status 2、在集群中所有主机上使用此命令&#xff0c;启动Zookeeper服务 $zkServer.sh start…

iOS 后台下载及管理库

说起下载第一个想起的就是ASI。一年前接手的新项目是核心功能是视频相关业务&#xff0c;在修改和解决视频下载相关的问题的时候让我体会到了ASI的下载的强大。后来新需求需要视频后台下载&#xff0c;使用NSURLSession的时候&#xff0c;更加深刻的体会到了ASI的强大好用。后来…

(转) 使用Speech SDK 5.1文字转音频

下载地址&#xff1a; http://www.microsoft.com/en-us/download/details.aspx?id10121 SeppchSDK51.exe 语音合成引擎 SpeechSDK51LangPack.exe 支持日语和简体中文需要这个支持。 SpeechSDK51MSM.exe 如果要将引擎作为产品的一部分发布需要这个。 Sp5TTintXP.exe XP下Mike和…

IE8下面的line-height的bug

当line-height小于正常值时&#xff0c;超出的部分将被剪裁掉转载于:https://www.cnblogs.com/jsingleegg/p/js_ie8.html

Hadoop集群的基本操作(一:HDFS操作及MapReduce程序练习)

实验 目的 要求 目的&#xff1a; 理解HDFS在Hadoop体系结构中的角色&#xff1b;熟练使用HDFS操作常用的Shell命令&#xff1b;了解Hadoop集群MapReduce程序的简单使用&#xff1b;&#xff08;上传WordCount的jar执行程序&#xff1b;使用WordCount进行MapReduce计算&#x…

iOS实现动态区域裁剪图片

阅读 249收藏 322017-11-29原文链接&#xff1a;github.com想自己动手搭建一个 Discuz 论坛&#xff1f;试试腾讯云上实验室吧https://cloud.tencent.com/developer/labs 裁剪图片功能在很多上传图片的场景里都需要用到&#xff0c;一方面应用服务器可能对图片的尺寸大小有限制…

每天CookBook之JavaScript-062

鼠标进入事件鼠标离开事件<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>062</title> </head> <body> <div><img src"001" alt"001"><img src…

spring + Quartz定时任务配置

<bean id"exportBatchFileTask" class"com.ydcn.pts.task.ExportBatchFileTask"></bean><bean id"readBatchFileTask" class"com.ydcn.pts.task.ReadBatchFileResultTask"></bean><!-- 生成开卡档&#xf…

Hadoop集群的基本操作(二:HBase的基本操作)

实验 目的 要求 目的&#xff1a; 1、HBase的基本应用 要求&#xff1a; 完成HBase的高可用完全分布模式的安装&#xff1b;HBase的相关服务进程能够正常的启动&#xff1b;HBase控制台能够正常使用&#xff1b;表创建、数据查询等数据库操作能够正常进行&#xff1b; …

Abaqus用户子程序umat的学习

Abaqus用户子程序umat的学习 说明&#xff1a;在文件中&#xff0c;&#xff01;后面的内容为注释内容。本文为学习心得&#xff0c;很多注释是自己摸索得到。如有不正确的地方&#xff0c;敬请指正。 ! —————————————————————————— ! 1、为何需要…

PHP:isset()-检测变量是否被设置

isset()-检测变量是否被设置 bool isset(mixed $var [, mixed $...])&#xff0c;检查变量是否被设置&#xff0c;并且不是NULL。var,要检测的变量&#xff0c;...其他变量&#xff0c;允许有多个变量。 返回值&#xff1a;如果var存在并且不是NULL&#xff0c;则返回TRUE&…

Android通过ShareSDK实现新浪微博分享

ShareSDK社会化分享的官方说明&#xff1a;是中国最大的APP内分享服务提供商&#xff0c;ShareSDK社会化分享&#xff0c;全面支持微信&#xff0c;微博&#xff0c;QQ空间&#xff0c;来往&#xff0c;易信&#xff0c;Facebook等国内外40个平台。 ShareSDK官方网站&#xff…

Hadoop集群的基本操作(三:HBase的基本操作)

实验 目的 要求 目的&#xff1a; MySQL数据库的基本命令&#xff1b;MySQL数据库中使用SQL语句&#xff1b;MySQL数据库中数据库&#xff0c;表&#xff0c;数据的操作&#xff1b;要求&#xff1a; 完成MySQL的集群版的安装&#xff1b;MySQL集群的相关服务进程能够正常启…

iOS通过Plist保存离线调试日志

最近需要测试APP在iPhone没连接USB情况下定位时间间隔的情况&#xff0c;固把nslog的日志信息保存成本地Plist文件&#xff0c;以便测试结束后查阅运行时的日志。 一、新建一个保存日志的方法&#xff0c;参数为每次定位成功的时间&#xff08;作为key&#xff09;&#xff0c…

关于变量名前面加m的问题

为什么很多人写代码会在变量名前面加一个小写的m&#xff1f; 上大学那会儿就对这个问题感到很好奇。于是网上到处搜&#xff0c;有人说是member的意思。于是后来一直就这么认为。 最近在读Android源码&#xff0c;发现很多系统变量命名时都加了m&#xff0c;而有的变量又没有加…

谷歌推出情境感知API

在 Google I/O 2016 大会上&#xff0c;我们宣布推出新的 Google Awareness API&#xff0c;让您的应用可以利用快照和围栏智能应对用户情境&#xff0c;并且仅需占用极少量的系统资源。 所有开发者均可以通过 Google Play 服务获取 Google Awareness API。 利用 7 种不同类型的…

Hadoop集群的基本操作(四:Hive的基本操作)

实验 目的 要求 目的&#xff1a; &#xff08;1&#xff09;掌握数据仓库工具Hive的使用&#xff1b; 要求&#xff1a; 掌握数据仓库Hive的使用&#xff1b;能够正常操作数据库、表、数据&#xff1b; 实 验 环 境 五台独立PC式虚…

【转】通过Hibernate将数据 存入oracle数据库例子

一、 Hibernate介绍 Hibernate是基于对象/关系映射&#xff08;ORM&#xff0c;Object/Relational Mapping&#xff09;的一个解决方案。ORM方案的思想是将对象模型表示的对象映射到关系型数据库中&#xff0c;或者反之。Hibernate目前是ORM思想在Java中最成功、最强大的实现。…

自动布局按钮排列平均分布

需要实现如下图所示的主页面布局&#xff0c;需要两排按钮&#xff0c;每一排都自动平均分布&#xff0c;Android的话直接用LinearLayout水平布局&#xff0c;并设置layout_weight即可&#xff0c;对于iOS&#xff0c;网上有使用代码实现&#xff0c;感觉略麻烦&#xff0c;我直…

maven3 手动安装本地jar到仓库

安装命令&#xff1a; mvn install:install-file -Dfile{Path/to/your/ojdbc.jar} -DgroupIdcom.oracle -DartifactIdojdbc6 -Dversion11.2.0 -Dpackagingjar我自己安装oracle14.jar 时命令如下&#xff1a;mvn install:install-file -DgroupIdcom.oracle -DartifactIdojdbc14 …

Hadoop集群的基本操作(五:Sqoop的基本操作)

实验 目的 要求 目的&#xff1a; 掌握ETL工具Sqoop的使用&#xff1b;掌握MySQL和HDFS之间的数据转换&#xff1b;要求&#xff1a; 掌握ETL工具Sqoop的使用&#xff1b;能够正常操作数据库、表、数据&#xff1b; 实 验 环 境 五台…