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

最终实现的效果如下:

Paste_Image.png

动态效果图:

shapeLayerAni.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.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.png

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

做好后的效果如下:

Paste_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
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

  1. iOS动画系列之九:实现点赞的动画及播放起伏指示器

    iOS动画系列,共十篇.现在写到第九篇啦.感兴趣的可以通过下面的传输门进到其他几篇文章里面. 第一篇:iOS动画系列之一:通过实战学习CALayer和透视的原理.做一个带时分秒指针的时钟动画(上) 第 ...

  2. iOS动画系列之五:基础动画之缩放篇旋转篇Swift+OC

    这一篇主要介绍基础动画之缩放和旋转.这些基本操作分享完之后,我想想可以找个稍微复杂一点点的动画做做啦. 这篇继续基础篇,分享一下缩放和旋转.因为整体思路和平移基本上没有变化,加上源代码里面也有OC版本 ...

  3. iOS动画系列之四:基础动画之平移篇

    就像咱们之前说的,所有的动画都是在CALayer上面的.所以在做动画之前我们就要先建立一个CALayer,然后把动画作用在自己创建的这个CALayer上.如果不知道CALyer是啥,可以看看前面的分享 ...

  4. iOS 动画系列之动画解释

    动画解释 译文 http://blog.jobbole.com/69111/ 原文 http://www.objc.io/issues/12-animations/animations-explain ...

  5. iOS开发系列--让你的应用“动”起来--超详细的ios核心动画介绍

    概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建基础动画.关键帧动画 ...

  6. CALayer与iOS动画 讲解及使用

    iOS CALayer与iOS动画 讲解及使用 关于CoreAnimation 初识CALayer CALayer CAAnimation CAMediaTiming UIView与CALayer动画 ...

  7. iOS开发系列--让你的应用“动”起来

    概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建基础动画.关键帧动画 ...

  8. iOS动画详解(学习动画看这一篇就够了)

    2019独角兽企业重金招聘Python工程师标准>>> 原文出处:wu大维 动效设计一直是iOS平台的优势,良好的动效设计可以很好地提升用户体验.而动画则是动效的基础支撑.本动画将从 ...

  9. iOS开发系列--UITableView全面解析

    iOS开发系列--UITableView全面解析 2014-08-23 23:20 by KenshinCui, 2202 阅读, 18 评论, 收藏,  编辑 --UIKit之UITableView ...

最新文章

  1. 【译】理解Javascript函数执行—调用栈、事件循环、任务等
  2. 去重仅保留一条_清水出芙蓉,天然去雕饰,牛仔背带裤配针织上衣的清纯温柔穿搭...
  3. androidstudio 日历视图怎么显示农历_记事日历-记事与时间管理工具
  4. strstr c语言字符串,C字符串处理strstr, strindex
  5. CG笔记之一——透视投影
  6. stm32正常运行流程图_stm32软件通信流程图
  7. Spring开发包介绍
  8. 【转】DCMTK 开源库的学习笔记2:直接操作dcm文件中像素数据的尝试
  9. sublime text3c语言编译运行,c – Sublime text 3 – 编译程序并在终端中运行
  10. 这把“锁”不简单,让你畅游数字世界
  11. python画棒棒糖程序_python之turtle简单绘制学习
  12. Python入门--with语句
  13. matlab乘与点乘的区别 (*与.* ^与.^)
  14. 重启Windows的PowerShell
  15. 关于spfile的一个难题
  16. mysql时间排序获取最新_mysql获取按日期排序获取时间最近的记录
  17. POJ3322解题报告
  18. Metasploit上使用RPC方式复现一个Linux提权漏洞
  19. Erlang词法分析器、语法分析器(lexer-leex,yac-yecc)
  20. snort--content中几个选项

热门文章

  1. zsh 每次打开Terminal都需要source bash_profile问题
  2. startActivityForResult和setResult详解
  3. Android源码编译过程之九鼎开发板
  4. java在继承中父类的成员变量是否会被子类所覆盖
  5. jquery选择器的使用方式
  6. POJ 1552 Doubles (C++ STL set使用)
  7. 原创:嵌入图片的HTML内容在FLASH AS3中正确显示的最佳解决方案
  8. PHP一些十分严重的缺陷
  9. Python3中参数*args和**kwargs介绍
  10. 概率论中指数分布介绍及C++11中std::exponential_distribution的使用