文章目录

  • 效果图
  • 前言
    • 1、绘制这个断断续续的进度条
      • 1.1 初始化一个贝塞尔直线
      • 1.2 使用CAShapeLayer初始化底部背景线,和进度线
      • 1.3 添加到视图上
    • 2 普通圆形进度条
      • 2.1首先开放公共参数
      • 2.2 使用贝赛尔曲线画圆
      • 2.2 使用CAShapeLayer初始化底部背景线,和进度线
    • 3 绘制渐变进度条
      • 3.1首先开放渐变公共参数
      • 3.2 使用CAGradientLayer设置渐变背景
      • 3.3 把进度圆环放到渐变背景上
    • 4 在进度条终点添加样式
      • 4.1 添加终点样式
      • 4.2 跟谁进度条速度加载
    • 5 仪表盘进度条样式
      • 5.1 公开参数
      • 5.2 初始化贝塞尔曲线,CAShapeLayer背景和进度条
  • 下面就说些我封装的进度条使用方法
  • demo 传送门

效果图

前言

ios 10.0

因为 UI 做了一些很别致的进度条效果图,而且在网上又找不到合适的三方库,自己在网上查查资料做了出来,然后整理了一下,分享给大家使用

首先,这个东西只是用贝赛尔曲线做出来的,并不是很难,做出来只是略微麻烦一点,网上也有很多资料,不过并不是很多,所以我就整理了一下,一是整理备份一下记录,二是分享给大家看下

1、绘制这个断断续续的进度条

UI 设计很漂亮,但是由于数据过多或过少,导致太难看,最后放弃

1.1 初始化一个贝塞尔直线

///贝塞尔直线
private lazy var path: UIBezierPath = {let bezierPath = UIBezierPath()bezierPath.move(to: CGPoint(x: 0, y: 0))bezierPath.addLine(to: CGPoint(x: bounds.size.width, y: 0))return bezierPath
}()

1.2 使用CAShapeLayer初始化底部背景线,和进度线

此处 lineDashPattern 是长度对比,一长一短线,我使用的是两个数据,多个的话,暂时没弄明白,有大佬了解的留个言,
建议:此处进度最好和你自己进度比率相同,要不然会出现上图的情况(一线两色)

///背景线
private lazy var backLayer: CAShapeLayer = {let layer = CAShapeLayer()layer.fillColor = UIColor.clear.cgColorlayer.strokeColor = .green.cgColorlayer.lineWidth = 2layer.lineDashPattern = [15, 3]layer.path = path.cgPathreturn layer
}()
///进度条线
private lazy var progressLayer: CAShapeLayer = {let layer = CAShapeLayer()layer.fillColor = UIColor.clear.cgColorlayer.strokeColor = .red.cgColorlayer.lineWidth = 2layer.lineDashPattern = [15, 3]layer.strokeStart = 0layer.strokeEnd = 0layer.path = path.cgPathreturn layer
}()

1.3 添加到视图上

直接设置 progressLayer.strokeEnd = progress 会显得突兀,我再此添加了一个动画,
后续此处就不一一说明

///数据
layer.addSublayer(backLayer)
layer.addSublayer(progressLayer)///进度
public var progress: CGFloat = 0.0 {didSet {CATransaction.begin()CATransaction.setDisableActions(false)CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: .linear))CATransaction.setAnimationDuration(2)progressLayer.strokeEnd = progressCATransaction.commit()}
}

2 普通圆形进度条

2.1首先开放公共参数

///背景颜色
public var backColor: UIColor = .gray
///进度条颜色
public var progressColor: UIColor = .red
///线宽
public var lineWidth: CGFloat = 2.0
///圆直径
public var realWidth: CGFloat = 100
///圆起点角度。角度从水平右侧开始为0,顺时针为增加角度。直接传度数 如-90
public var startAngle: CGFloat = 0.5 * .pi
///圆结束角度。角度从水平右侧开始为0,顺时针为增加角度。直接传度数 如-90
public var endAngle: CGFloat = 0.5 * .pi
///动画时长
public var duration: CGFloat = 2

2.2 使用贝赛尔曲线画圆

设置中心点、半径(通过直径 - 宽度计算得来)、起始位置,结束位置

let radius = realWidth / 2 - lineWidth///贝塞尔直线
private lazy var path: UIBezierPath = {let bezierPath = UIBezierPath(arcCenter: CGPoint(x: realWidth/2, y: realWidth/2),radius: radius,startAngle: startAngle,endAngle: 2 * .pi + endAngle,clockwise: true)return bezierPath
}()

2.2 使用CAShapeLayer初始化底部背景线,和进度线

然后 添加到视图,和设置进度我就不说了,上面都有, 至于是多少角度的圆形,设置起始角度和结束角度就可以了

///背景圆环
private lazy var backLayer: CAShapeLayer = {let layer = CAShapeLayer()layer.frame         = boundslayer.fillColor     = UIColor.clear.cgColorlayer.lineWidth     = lineWidthlayer.strokeColor   = backColor.cgColorlayer.lineCap       = .roundlayer.path          = path.cgPathreturn layer
}()///进度圆环
private lazy var progressLayer: CAShapeLayer = {let layer = CAShapeLayer()layer.frame         = boundslayer.fillColor     = UIColor.clear.cgColorlayer.lineWidth     = lineWidthlayer.strokeColor   = progressColor.cgColorlayer.lineCap       = .roundlayer.path          = path.cgPathlayer.strokeEnd     = 0return layer
}()

3 绘制渐变进度条

3.1首先开放渐变公共参数

相同参数我就不在一一叙述

///渐变颜色
public var colors: [CGColor] = [UIColor.red.cgColor, UIColor.green.cgColor]
///渐变色位置
public var locations: [NSNumber] = [0, 1]
///渐变色起始位置
public var startPoint: CGPoint = CGPoint(x: 0, y: 0)
///渐变色结束位置
public var endPoint: CGPoint = CGPoint(x: 1, y: 0)

3.2 使用CAGradientLayer设置渐变背景

///渐变背景
private lazy var gradientLayer: CAGradientLayer = {let layer = CAGradientLayer()layer.frame = boundslayer.colors =  colorslayer.locations =  locationslayer.startPoint =  startPointlayer.endPoint =  endPointreturn layer
}()

3.3 把进度圆环放到渐变背景上

然后加载进度就可以了

gradientLayer.mask = progressLayer
layer.addSublayer(gradientLayer)

4 在进度条终点添加样式

4.1 添加终点样式

此处我使用了 UIView,你可以采用图片、渐变 view 等
在 layer.addSublayer(progressLayer) 后面放入,

addSubview(dot)
dot.isHidden = true

4.2 跟谁进度条速度加载

使用 CAAnimation 加载动画
整圆和非整圆这块加载我没给弄清楚,有了解的大佬请给予指出,虽然结果没错,但是两套逻辑总感觉很奇怪

private lazy var pointAnimation: CAAnimation = {let animation = CAKeyframeAnimation(keyPath: "position")animation.timingFunction = CAMediaTimingFunction(name: .linear)animation.fillMode = .forwardsanimation.calculationMode = CAAnimationCalculationMode.pacedanimation.isRemovedOnCompletion = falseanimation.duration = duration///此处记得加载代理,不用执行方法animation.delegate = selfvar end = 2 * .pi * progress + startAngle///非整圆if data.startAngle != data.endAngle {end = (2 * .pi - CGFloat(fabs(Double(endAngle))) - startAngle) * progress + startAngle}let imagePath = UIBezierPath(arcCenter: CGPoint(x: realWidth/2, y: realWidth/2),radius: radius,startAngle: startAngle,endAngle: end,clockwise: true)animation.path = imagePath.cgPathreturn animation
}()

执行加载动画, 此处跟谁到 progress 设置进度后面即可

dot.isHidden = false
dot.layer.add(pointAnimation, forKey: "pointAnimation")

5 仪表盘进度条样式

5.1 公开参数

此处总长度是圆周长长度,这个切记要计算好,否则最后一根线会有问题

///线间距 间断进度条专属  直线计算长度,圆计算周长
public var lineDashPattern: [NSNumber] = [15 , 5]

5.2 初始化贝塞尔曲线,CAShapeLayer背景和进度条

///贝塞尔直线
private lazy var path: UIBezierPath = {let bezierPath = UIBezierPath(arcCenter: CGPoint(x: data.realWidth / 2, y: data.realWidth / 2),radius: radius,startAngle: startAngle,endAngle: 2 * .pi + endAngle,clockwise: true)return bezierPath
}()
///背景
private lazy var backLayer: CAShapeLayer = {let layer = CAShapeLayer()layer.frame         = boundslayer.fillColor     = UIColor.clear.cgColorlayer.lineWidth     = lineWidthlayer.strokeColor   = backColor.cgColorlayer.path          = cgPathlayer.lineDashPattern = lineDashPatternreturn layer
}()
///进度条
private lazy var progressLayer: CAShapeLayer = {let layer = CAShapeLayer()layer.frame         = boundslayer.fillColor     = UIColor.clear.cgColorlayer.lineWidth     = lineWidthlayer.strokeColor   = progressColor.cgColorlayer.path          = path.cgPathlayer.strokeEnd     = 0layer.lineDashPattern = lineDashPatternreturn layer
}()

添加和设置进度和之前一样,我就不一一赘述

下面就说些我封装的进度条使用方法

封装的demo中有案例
1、通过设置 type 类型,添加各种类型的进度条

let newView = HJProgress(frame: CGRect(x: 10, y: 110, width: 120, height: 120))
newView.type = .circle

2、通过设置HJData() 设置各种参数,添加数据之后,才会出现进度条

var data = HJData()
data.realWidth = 120
data.lineWidth = 2
newView.data = data

3、通过设置progress 加载进度条

demo 传送门

具体例子看我下面 github 的 demo 吧,欢迎来提建议
demo

CSDN 上ZIP 压缩包(免积分)
HJProgress

Swift 圆形进度条相关推荐

  1. android 自定义音乐圆形进度条,Android自定义View实现音频播放圆形进度条

    本篇文章介绍自定义View配合属性动画来实现如下的效果 实现思路如下: 根据播放按钮的图片大小计算出圆形进度条的大小 根据音频的时间长度计算出圆形进度条绘制的弧度 通过Handler刷新界面来更新圆形 ...

  2. Swift 圆环进度条

    Swift 圆环进度条 import UICircularProgressRing import UIKit import UICircularProgressRing class ViewContr ...

  3. Android自定义控件NumberCircleProgressBar(圆形进度条)的实现

    Android自定义控件NumberCircleProgressBar(圆形进度条)的实现

  4. html进度条圆圈渐变色,HTML5 canvas带渐变色的圆形进度条动画

    jquery-circle-progress是一款带渐变色的圆形进度条动画特效jQuery插件.该圆形进度条使用的是HTML5 canvas来绘制圆形进度条及其动画效果,进度条使用渐变色来填充,效果非 ...

  5. 微信小程序之圆形进度条(自定义组件)

    前言 昨天在微信小程序实现了圆形进度条,今天想把这个圆形进度条做成一个组件,方便以后直接拿来用. 根据官方文档自定义组件一步一步来 创建自定义组件 第一步创建项目结构 打开微信开发者工具创建一个项目, ...

  6. Android 之 ProgressDialog用法介绍(矩形进度条 和 圆形 进度条)

    2019独角兽企业重金招聘Python工程师标准>>> 布局文件: <LinearLayout xmlns:android="http://schemas.andro ...

  7. 【Android 应用开发】 自定义 圆形进度条 组件

    转载著名出处 : http://blog.csdn.net/shulianghan/article/details/40351487 代码下载 : -- CSDN 下载地址 : http://down ...

  8. android 环形时间显示_Android圆形进度条颜色的设置

    最近几天由于项目的需要研究了一下listView的滑动数据动态的更新显示,其中需要在数据加载过程有圆形进度条的显示,遇到的问题是进度条的颜色设置,在网上查了一些资料结合自己的所得分享在此. xml布局 ...

  9. Android自定义圆形进度条

    Android自定义圆形进度条 github地址:https://github.com/opq1289/CircleProgressView 效果图: 无动画: 有动画: 整圆: 切割圆: 具体步骤: ...

  10. Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)

    转载请注明地址:http://blog.csdn.net/xiaanming/article/details/10298163 很多的时候,系统自带的View满足不了我们功能的需求,那么我们就需要自己 ...

最新文章

  1. 数据插入INSERT
  2. 2018 多校联合训练 10
  3. php中nodethirtythree,node常用模块 - LinearLaw的个人空间 - OSCHINA - 中文开源技术交流社区...
  4. 如何在 C# 中使用 yield
  5. 放大器非线性失真研究装置_高效布里渊光纤放大器
  6. Java import static静态导入
  7. 什么是Web渗透测试
  8. Android 匿名共享内存驱动源码分析
  9. RHEL6入门系列之三十三,写在最后
  10. Mac 右键的一些方法
  11. Blender - Proportional Edit Mode - 按比例编辑模式(3D版的液化、挤压工具)
  12. IOS中使用getUserMedia获取视频流展示到video中,进行人脸识别
  13. SQL查询——查询和和xxx同学所选课程完全一样的同学
  14. 我们研究了853场世界杯比赛,发现了这几条稳赔不赚的竞猜攻略
  15. IT视频教程百度云盘链接分享
  16. #9.白盒测试:数据流测试
  17. 免费的网盘您知道哪些?
  18. 巨坑警告!程序员去银行写代码千万别去分行
  19. centos6.5环境基于conga的web图形化界面方式配置rhcs集群
  20. 安装一套无人值守称重系统需要多少人

热门文章

  1. qq空间显示手机型号android,手机qq空间发说说怎么修改/隐藏显示的手机型号?
  2. 转载:Xshell使用教程
  3. 专利局文件如何删除后面的注意事项
  4. HART/EtherNet IP网关HEI-612
  5. 普元EOS7.x及以下版本升级Tomcat8
  6. 签到活动 测试要点分析
  7. AOD实践,modis数据下载,modis数据处理,
  8. AForge.net库类下载方式
  9. 实用的文字转语音免费软件推荐
  10. Win32_1深入浅出windows消息机制