概述

今天我们来实现一个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的顶部

主要的接口有以下几个:

+ (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数组来实现不同颜色的色带:

    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 sectionNSMutableArray *colors = [NSMutableArray array];for (NSInteger deg = 0; deg <= 360; deg += 5) {UIColor *color;color = [UIColor colorWithHue:1.0 * deg / 360.0saturation:1.0brightness:1.0alpha:1.0];[colors addObject:(id)[color CGColor]];}[self.gradLayer setColors:[NSArray arrayWithArray:colors]];

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

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

/***  here I use timer to circularly move colors*/
- (void)setupTimer
{CGFloat interval = 0.03;if (self.timer == nil) {self.timer = [NSTimer timerWithTimeInterval:interval target:selfselector:@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的启动、暂停、永远停止这三个操作要分清,尤其是暂停与停止:

  • 启动:  
- (void)startTimer
{//start timer[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];[self.timer setFireDate:[NSDate date]];
}

  • 暂停:
/***  here we just pause timer, rather than stopping forever.*  NOTE: [timer invalidate] is not fit here.*/
- (void)pauseTimer
{[self.timer setFireDate:[NSDate distantFuture]];
}

  • 停止(无法再启动):
[self.timer invalidate]

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

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

CALayer *layer = new
layer.mask = _maskLayer;
layer.visualSection = _maskLayer.bounds;

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

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

    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];

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

- (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,给我更多支持与鼓励!

源代码下载:点我。https://github.com/weng1250/WGradientProgressDemo.git


原创文章,转载请注明 编程小翁@博客园,邮件zilin_weng@163.com,欢迎各位与我在C/C++/Objective-C/机器视觉等领域展开交流!


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

  1. c#WinForm自定义控件 渐变颜色的进度条

    C#WinForm工具箱自带的ProgressBar进度条控件的颜色默认为绿色,没有属性用来修改,很不方便.所以我们就需要重绘ProgressBar控件来达到我们想要的效果. 完成效果: 实现了进度条 ...

  2. CSS锥形渐变实现环形进度条

    10月份因为疫情原因.又开启了居家办公模式,空闲之余,与其选择"躺平",不如去做一些有意义的事情,内心的想法驱使着我去做些什么,但是又没有合适的素材,直到接手了最近的一个可视化项目 ...

  3. Android 带文字的进度条,文字颜色随进度条的增加而渐变的效果

    Android自带的ProgressBar是不带文字的,加文字的话可以参考这篇博客:http://blog.csdn.net/lixiaodaoaaa/article/details/9852327 ...

  4. iOS实现一个颜色渐变的弧形进度条

    在Github上看到一些进度条的功能,都是通过Core Graph来实现.无所谓正确与否,但是开发效率明显就差很多了,而且运行效率还是值得考究的.其实使用苹果提供的Core Animation能够非常 ...

  5. ios弧形进度条_【iOS实现一个颜色渐变的弧形进度条】

    在Github上看到一些进度条的功能,都是通过Core Graph来实现.无所谓正确与否,但是开发效率明显就差很多了,而且运行效率还是值得考究的.其实使用苹果提供的Core Animation能够非常 ...

  6. windows下flv视频网站进度条随意拖放[转]

    网站中视频都转换成flv格式,奈何flv格式无法拖拽,此问题纠结了好久,最终得以解决.现将解决思路记录下来,大多数源于网上找到的. 视频拖拽满足要求 1.播放器要支持 2.flv视频要有关键帧和met ...

  7. Android 自带描边颜色渐变炫酷进度条

    /** 外描边的宽度 */ private float BORDER_STROCK; /** 进度条进度矩形与控件边界的距离,≥BORDER_STROCK */ private float PROGR ...

  8. Android 自带描边颜色渐变炫酷进度条,面试必知必会

    3. 画第三个圆角矩形作为进度条的最外层(进度层)盖在背景层之上 4. 描边层和背景层颜色可用纯色,进度层为了炫酷可用渐变色 这是实现该自带描边颜色渐变进度条的原理,也是在PS中实现该效果的步骤,同样 ...

  9. IOS 开发 UIProgress 和 UISlidre 进度条和滑动条组件

    进度条和滑动条组件非常常见,在ios中进度条组件是无法响应事件的.滑动条可响应事件.但是这两个组件均不可设置高度,可设置x,y,width 进度条属性 名称 类型 说明 默认值 progressVie ...

最新文章

  1. 浅析微信支付:统一下单接口
  2. 银行加速“去房地产化”
  3. Linux搭建lamp(Apache+PHP+Mysql环境)centos7.2版详细教程
  4. HTML小知识点积累
  5. 【转载】生怕我等着急了的扬州程序员
  6. 白鹭引擎解决微信小游戏切换背景音乐无法播放的问题。
  7. Mac 如何寻找Mac自带的IDLE
  8. .htaccess使用说明
  9. 机器学习- 吴恩达Andrew Ng Week6 知识总结 Machine Learning System Design
  10. matlab用ezplot绘制参数方程,MATLAB学习1 之画图函数
  11. 关于C语言两个小游戏的提示和源码(猜词游戏与控制移动游戏)
  12. 控制WINDOWS,使电脑说话的小玩意
  13. 2020ECCV|EPNet: Enhancing Point Features with Image Semantics for 3D Object Detection阅读笔记
  14. 多多参谋参谋|拼多多店群什么产品容易成为爆款呢|魔店分享
  15. Extjs中加载异步树的最简单例子实现
  16. 计算机出现蓝屏怎么解决,电脑出现蓝屏,什么原因,怎么办?
  17. 服务器性能参数:QPS、PV、IP
  18. 万达商业再递招股书:上半年派息35亿 腾讯与碧桂园是股东
  19. 艾美捷CpG-A DNA,人/小鼠的功能和应用
  20. 使用PowerApps制作请假系统(一)--创建SharePoint列表以及PowerApps主题部分

热门文章

  1. 15000 字的 SQL 语句大全
  2. Spring的Controller是单例还是多例?怎么保证并发的安全
  3. JAVA多线程和并发基础面试问答
  4. GNN教程:DGL框架中的采样模型!
  5. 特斯拉AI总监:我复现了LeCun 33年前的神经网络,发现和现在区别不大
  6. 腾讯视频招GNN方向实习生啦~
  7. Keras创始人:过去6个月,深度学习岗位已崩溃
  8. 腾讯工程师总结的Python面试指南PDF,开放下载
  9. 如何逐步打下(研究生/博士生阶段)深度学习的数学基础?
  10. CNN是靠什么线索学习到深度信息的?——一个经验性探索