【原】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,如需转载请自行联系原作者

相关文章
|
Apache 数据安全/隐私保护 Docker
【开源问答系统】GitHub 14.9k star 的开源问答引擎来了,三分钟搭建完成~~~
Apache Answer 是一款开源问答系统,助力团队将零散知识沉淀为结构化资产。支持 Docker 快速部署、插件扩展、权限控制与多语言,兼具高效搜索、投票排序与私有化部署能力,适用于技术社区、企业知识库与用户支持场景。
1361 22
|
人工智能 JavaScript 前端开发
Github 2024-10-28 开源项目周报 Top15
本周GitHub热门项目涵盖Svelte、Open Interpreter、PowerShell等,涉及Web开发、AI助手、自动化工具等领域,Python、JavaScript为主流语言,展现开源技术活跃生态。(239字)
1179 19
|
人工智能 JavaScript 前端开发
Github 2024-11-04 开源项目周报 Top14
本周GitHub热门项目涵盖屏幕截图转代码、网页监控、低代码开发等。Python与TypeScript主导,亮点项目包括AI生成代码工具、开源社交应用Bluesky及机器人框架LeRobot,展现AI与自动化技术的快速发展趋势。
671 15
|
人工智能 JavaScript Docker
Github 2024-11-11 开源项目周报 Top15
本周GitHub热门项目涵盖多领域:Python与TypeScript领跑,包括屏幕截图转代码、本地文件共享、PDF处理、AI开发代理等。亮点项目如screenshot-to-code、LocalSend、OpenHands及Diagrams,兼具创新与实用性,广受开发者关注。
1091 13
|
缓存 自然语言处理 JavaScript
抓紧上车,别再错过啦, Github 开源后台管理平台,Naive UI !!!
naive-ui-pro 是基于 Vue3 + Vite + TypeScript 的免费开源中后台模板,主打“路由插件化架构”,将权限、页签、缓存等功能拆解为可插拔模块,像搭积木一样灵活组装。内置 14+ 插件、Pro Naive UI 组件库与丰富示例,支持移动端适配、多主题、国际化,MIT 许可,开箱即用,助力高效开发。
1589 4
|
人工智能 算法 JavaScript
Github 2024-10-14 开源项目周报 Top14
本周GitHub热门项目共14个,Python项目占7席。涵盖算法实现、生成式AI、金融分析、目标检测等领域,包括TheAlgorithms系列、OpenBB金融平台、Ultralytics YOLO11、Manim动画框架等,展现开源技术多元发展态势。
540 8
|
人工智能 Rust JavaScript
Github 2024-10-07 开源项目周报 Top15
本周GitHub热门项目共15个,Python项目占比最高达7个。榜首为Python算法实现集合TheAlgorithms/Python,Star数超17万;其他亮点包括Godot游戏引擎、OpenBB金融平台、ToolJet低代码框架及新兴AI相关项目如Crawl4AI、Llama Stack等,涵盖游戏、金融、AI、理财等多个领域。
583 4
|
人工智能 Rust 算法
Github 2024-09-30 开源项目周报 Top15
本周GitHub热门项目揭晓:Python主导,AutoGPT居首,涵盖AI、编程、数学动画等领域,助力开发者探索前沿技术。
514 4
|
人工智能 JavaScript 前端开发
Github 2024-09-16 开源项目周报 Top14
本周GitHub热门项目涵盖Python、TypeScript、Go等语言,React居首。亮点包括微软PowerToys、Node版本管理器、AI证件照工具HivisionIDPhotos及端侧大模型MiniCPM等。
425 2
|
Rust JavaScript 安全
Github 2024-09-02 开源项目周报 Top13
本周GitHub热门项目涵盖AI、开发工具与开源替代品。包括Notion替代AppFlowy、Airtable替代NocoDB、云平台Coolify及可观察性平台OpenObserve等,涉及Python、TypeScript、Rust等语言,聚焦效率、隐私与自动化。
655 1

热门文章

最新文章