【原】Github系列之三:开源iOS下 渐变颜色的进度条WGradientProgress

简介:

概述

今天我们来实现一个iOS平台上的进度条(progress bar or progress view)。这种进度条比APPLE自带的更加漂亮,更加有“B格”。它拥有渐变的颜色,而且这种颜色是动态移动的,这里称之为WGradientProgress。

先来看看我们的目标长什么样子:

   

 

WGradientProgress的使用方法很简单,主要有展示接口以及隐藏接口,目前显示的位置有两种选择:

  • WProgressPosDown        //progress is on the down border of parent view,显示在parent view的底部(主流做法,默认)

  • WProgressPosUp           //progress is on the up border of parent view,也就是显示在parent view的顶部

 

主要的接口有以下几个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
+ (WGradientProgress *)sharedInstance;
 
/**
  *  the main interface to show WGradientProgress obj, position is WProgressPosDown by default.
  *
  *  @param parentView which view to be attach
  */
- ( void )showOnParent:(UIView *)parentView;
 
/**
  *  the main interface to show WGradientProgress obj
  *
  *  @param parentView which view to be attach
  *  @param pos        up or down
  */
- ( void )showOnParent:(UIView *)parentView position:(WProgressPos)pos;
 
/**
  *  the main interface to hide WGradientProgress obj
  */
- ( void )hide;

  


 

分析

 

这里我们看一下,实现出这样的效果需要解决哪些技术难点:

  • 如何实现一个静态的具有渐变颜色的色带
  • 如何实现色带颜色循环移动
  • 如何关联进度值与色带的宽度

 

(1)如何实现一个静态的具有渐变颜色的色带

这里需要使用CALayer的子类CAGradientLayer。CAGradientLayer用于实现颜色渐变,关于CAGradietnLayer的介绍请看这里。我们使用到的属性有startPoint、endPoint、colors。

我们可以这样子做出一个静态的渐变色带,你也可以修改colors数组来实现不同颜色的色带:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if  ( self .gradLayer ==  nil ) {
     self .gradLayer = [CAGradientLayer layer];
     self .gradLayer.frame =  self .bounds; //尺寸要与view的layer一致
}
self .gradLayer.startPoint = CGPointMake(0, 0.5);
self .gradLayer.endPoint = CGPointMake(1, 0.5);
 
//create colors, important section
NSMutableArray  *colors = [ NSMutableArray  array];
for  ( NSInteger  deg = 0; deg <= 360; deg += 5) {
     
     UIColor *color;
     color = [UIColor colorWithHue:1.0 * deg / 360.0
                        saturation:1.0
                        brightness:1.0
                             alpha:1.0];
     [colors addObject:( id )[color CGColor]];
}
[ self .gradLayer setColors:[ NSArray  arrayWithArray:colors]];

 

 (2)如何实现色带颜色循环移动

色带颜色循环向前移动,本质上是渐变图层gradientLayer的colors数组循环变化。如果理解了这点,那就很容易往下做了。我的做法是使用定时器NSTimer,让定时器的执行方法去循环地改变color数组。另外,既然要做到循环,那么应该循环地取colors数组的最后一个颜色值插到数组开始处。定时器的执行代码如下:

 

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
28
/**
  *  here I use timer to circularly move colors
  */
- ( void )setupTimer
{
     CGFloat interval = 0.03;
     if  ( self .timer ==  nil ) {
          self .timer = [ NSTimer  timerWithTimeInterval:interval target: self
                                             selector: @selector (timerFunc)
                                             userInfo: nil  repeats: YES ];
     }
     [[ NSRunLoop  currentRunLoop] addTimer: self .timer forMode: NSDefaultRunLoopMode ];
}
 
/**
  *  rearrange color array
  */
- ( void )timerFunc
{
     CAGradientLayer *gradLayer =  self .gradLayer;
     NSMutableArray  *copyArray = [ NSMutableArray  arrayWithArray:[gradLayer colors]];
     UIColor *lastColor = [copyArray lastObject];
     [copyArray removeLastObject];
     if  (lastColor) {
         [copyArray insertObject:lastColor atIndex:0];
     }
     [ self .gradLayer setColors:copyArray];
}

  


*强势插入:

  NSTimer的启动、暂停、永远停止这三个操作要分清,尤其是暂停与停止:

  • 启动:  
1
2
3
4
5
6
- ( void )startTimer
{
     //start timer
     [[ NSRunLoop  currentRunLoop] addTimer: self .timer forMode: NSDefaultRunLoopMode ];
     [ self .timer setFireDate:[ NSDate  date]];
}
  • 暂停:
1
2
3
4
5
6
7
8
/**
  *  here we just pause timer, rather than stopping forever.
  *  NOTE: [timer invalidate] is not fit here.
  */
- ( void )pauseTimer
{
     [ self .timer setFireDate:[ NSDate  distantFuture]];
}
  •  停止(无法再启动):
1
[ self .timer invalidate]

(3)如何关联进度值与色带的宽度

这个问题看起来很简单,但实际上隐藏着一个很好用的技术:mask。mask也称为蒙版,当我们给一个layer设置了mask layer后,layer就只显示出mask layer所覆盖到的区域,其他区域不显示。用伪代码可以描述为:

 

1
2
3
CALayer *layer =  new
layer.mask = _maskLayer;
layer.visualSection = _maskLayer.bounds;

 

因此,我们可以将在一开始时就上文的渐变图层gradientLayer大小设置为与view同尺寸,然后通过mask layer设置可见区域。这样,进度条进度值设置问题就转化为mask layer的宽度问题了。

首先,我们添加一个mask layer到gradient layer上:

 

1
2
3
4
5
6
7
self .mask = [CALayer layer];
[ self .mask setFrame:CGRectMake( self .gradLayer.frame.origin.x,  self .gradLayer.frame.origin.y,
                                self .progress *  self .width,  self .height)];
self .mask.borderColor = [[UIColor blueColor] CGColor];
self .mask.borderWidth = 2;
[ self .gradLayer setMask: self .mask];
[ self .layer addSublayer: self .gradLayer];

 

然后相应进度值的改变如下:

 

1
2
3
4
5
6
7
8
9
10
11
12
- ( void )setProgress:(CGFloat)progress
{
     if  (progress < 0) {
         progress = 0;
     }
     if  (progress > 1) {
         progress = 1;
     }
     _progress = progress;
     CGFloat maskWidth = progress *  self .width;
     self .mask.frame = CGRectMake(0, 0, maskWidth,  self .height);
}

 

 以上就是WGradientProgress的主要技术要点,更具体的细节以及使用方法请下载我github上的代码查看,下载时别忘记随手点个Star,给我更多支持与鼓励!

本文转自编程小翁博客园博客,原文链接:http://www.cnblogs.com/wengzilin/p/4665038.html,如需转载请自行联系原作者

相关文章
|
2月前
|
移动开发 网络协议 小程序
基于开源IM即时通讯框架MobileIMSDK:RainbowChat-iOS端v9.1版已发布
RainbowChat是一套基于开源IM聊天框架 MobileIMSDK 的产品级移动端IM系统。RainbowChat源于真实运营的产品,解决了大量的屏幕适配、细节优化、机器兼容问题
64 5
|
29天前
|
存储 Linux 数据安全/隐私保护
一键部署 200+ 开源Github 2k+ 星星的软件
Websoft9面板是一款基于Web的PaaS/Linux面板,支持在个人服务器上一键部署200多种热门开源应用,适用于个人开发者、中小企业、创业团队、教育机构和技术爱好者。它集成了丰富的开源软件,提供便捷的部署方式、高效的资源利用、良好的可扩展性及低技术门槛,帮助用户快速搭建和管理各类应用。
|
2月前
|
编解码 人工智能 自然语言处理
MaskGCT:登上GitHub趋势榜榜首的TTS开源大模型
近日,香港中文大学(深圳)联手趣丸科技推出了新一代大规模声音克隆TTS模型——MaskGCT。一起看看该模型的一些表现吧!
|
2月前
|
数据采集 应用服务中间件 Go
开源的键鼠共享工具「GitHub 热点速览」
开源的键鼠共享工具「GitHub 热点速览」
|
4月前
|
SQL JavaScript 前端开发
Github 2024-08-05 开源项目周报 Top15
根据 Github Trendings 的统计,本周(2024年8月5日统计)共有15个项目上榜。以下是根据开发语言汇总的项目数量: - Go 项目:4个 - JavaScript 项目:3个 - Python 项目:3个 - Java 项目:2个 - TypeScript 项目:2个 - C 项目:1个 - Shell 项目:1个 - Dockerfile 项目:1个 - 非开发语言项目:1个
139 2
|
4月前
|
人工智能 Rust JavaScript
Github 2024-08-26 开源项目周报Top15
根据Github Trendings的统计,本周共有15个项目上榜。以下是按开发语言汇总的项目数量:Python项目8个,TypeScript、C++ 和 Rust 项目各2个,Jupyter Notebook、Shell、Swift 和 Dart 项目各1个。其中,RustDesk 是一款用 Rust 编写的开源远程桌面软件,可作为 TeamViewer 的替代品;Whisper 是一个通用的语音识别模型,基于大规模音频数据集训练而成;初学者的生成式人工智能(第2版)则是由微软提供的18门课程,教授构建生成式AI应用所需的知识。
142 1
|
4月前
|
Rust Dart 前端开发
Github 2024-08-19 开源项目周报Top15
根据Github Trendings的统计,本周(2024年8月19日统计)共有15个项目上榜。按开发语言分类,上榜项目数量如下:Python项目最多,有7项;其次是JavaScript和TypeScript,各有3项;Dart有2项;HTML、PowerShell、Clojure和C++各1项。此外,还介绍了多个热门项目,包括Bootstrap 5、RustDesk、ComfyUI、易采集、Penpot等,涵盖了Web开发、远程桌面、自动化测试、设计工具等多个领域。
123 1
|
4月前
|
JavaScript 前端开发 Go
Github 2024-08-12 开源项目周报 Top14
本周Github Trendings共有14个项目上榜,按开发语言汇总如下:Python项目7个,TypeScript项目5个,C项目2个,JavaScript项目2个,Go和Batchfile项目各1个。其中亮点包括开发者职业成长指南、Windows激活工具、ComfyUI图形界面、AFFiNE知识库、易采集可视化爬虫等项目,涵盖多种实用工具和开源平台。
148 1
|
4月前
|
存储 JavaScript 前端开发
Github 2024-07-29 开源项目周报Top15
根据 Github Trendings 的统计,本周(2024年7月29日统计)共有15个项目上榜。按开发语言分类,项目数量如下:Python、Java、HTML 和 C 项目各有2项;TypeScript、JavaScript、Vue 和 Go 各有1项;另有1项非特定语言项目、1项 Dart 项目、1项 C++ 项目、1项 Rust 项目及1项 Jupyter Notebook 项目。这些项目涵盖了多种领域,如API开发、照片管理、PDF处理、AI技术等。
70 1
|
4月前
|
Rust JavaScript 前端开发
Github 2024-07-15 开源项目周报 Top15
根据 Github Trendings 的统计,2024年7月15日当周共有15个项目上榜。以下是按开发语言分类的项目数量汇总:Python项目5个,非开发语言项目4个,JavaScript项目3个,TypeScript项目2个,Go、Solidity和Java项目各1个,Rust项目1个。此外,介绍了多个值得关注的项目,包括免费编程学习平台 freeCodeCamp.org、免费编程书籍和学习资源清单、免费 API 集合等,涵盖了不同编程语言和技术领域。
60 1
下一篇
DataWorks